package com.ygy.test.sort;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import java.util.*;
/**
* Created by guoyao on 2017/10/11.
*/
public class TopologicalSorting {
private static class Vertex {
@Getter @Setter
private int indegree;
@Getter @Setter
private String name ;
public Vertex(String name) {
this.name=name;
indegree = 0 ;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Vertex vertex=(Vertex) o;
return name.equals(vertex.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
private static class TopoGraph {
public Map<Vertex, Set<Vertex>> relMap=new HashMap<>();
public Set<Vertex> vertices=new HashSet<>();
public boolean addRelVertex(Vertex start, Vertex end) {
vertices.add(start);
vertices.add(end);
Set<Vertex> adjcents=relMap.get(start);
if (CollectionUtils.isEmpty(adjcents)) {
adjcents = new HashSet<>();
}
if (adjcents.contains(end)) {
return false;
}
adjcents.add(end);
int indegree=end.getIndegree();
end.setIndegree(++indegree);
relMap.put(start, adjcents);
return true;
}
}
public static List<Vertex> topo_sort(TopoGraph topoGraph) throws Exception {
Queue<Vertex> zeroIndegree=new LinkedList<>();
List<Vertex> resultList=new ArrayList<>();
int count = topoGraph.vertices.size() ;
for (Vertex vertex : topoGraph.vertices) {
int indegree=vertex.getIndegree();
if (indegree == 0) {
zeroIndegree.add(vertex);
}
}
while (!zeroIndegree.isEmpty()) {
Vertex vertex=zeroIndegree.poll();
resultList.add(vertex);
Set<Vertex> adjacents=topoGraph.relMap.get(vertex);
if (!CollectionUtils.isEmpty(adjacents)) {
for (Vertex adj : adjacents) {
int indegree=adj.getIndegree();
adj.setIndegree(--indegree);
if (0 == indegree) {
zeroIndegree.add(adj);
}
}
}
}
if (count != resultList.size()) {
throw new RuntimeException(" 闭环");
}
return resultList;
}
public static void main(String[] args) throws Exception {
Vertex vertexA=new Vertex("A");
Vertex vertexB=new Vertex("B");
Vertex vertexC=new Vertex("C");
Vertex vertexD=new Vertex("D");
Vertex vertexE=new Vertex("E");
TopoGraph topoGraph=new TopoGraph();
topoGraph.addRelVertex(vertexA, vertexB);
topoGraph.addRelVertex(vertexC, vertexD);
topoGraph.addRelVertex(vertexB, vertexD);
topoGraph.addRelVertex(vertexD, vertexE);
List<Vertex> result=null;
result = topo_sort(topoGraph);
if (result != null) {
for (Vertex vertex : result) {
System.out.println(vertex.getName());
}
}
}
}