import java.util.*;
/**
* 拓扑排序:(1)在有向图中选一个没有前驱的顶点且输出之 (2)从图中删除该顶点和所有以它为尾的弧
* 重复以上两步骤,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。后者说明有向图中有环。
**/
public class TopologicalTest {
private static final int V_COUNT = 12;
public static void main(String[] args) {
//初始化节点
Topological topological1 = new Topological("C1", 0, new ArrayList());
Topological topological2 = new Topological("C2", 1, new ArrayList());
Topological topological3 = new Topological("C3", 2, new ArrayList());
Topological topological4 = new Topological("C4", 1, new ArrayList());
Topological topological5 = new Topological("C5", 2, new ArrayList());
Topological topological6 = new Topological("C6", 1, new ArrayList());
Topological topological7 = new Topological("C7", 2, new ArrayList());
Topological topological8 = new Topological("C8", 2, new ArrayList());
Topological topological9 = new Topological("C9", 0, new ArrayList());
Topological topological10 = new Topological("C10", 1, new ArrayList());
Topological topological11 = new Topological("C11", 1, new ArrayList());
Topological topological12 = new Topological("C12", 3, new ArrayList());
//将节点添加后驱
List list = topological1.getTopologicals();
list.add(topological2);
list.add(topological4);
list.add(topological12);
list.add(topological3);
topological1.setTopologicals(list);
list = topological2.getTopologicals();
list.add(topological3);
topological2.setTopologicals(list);
list = topological3.getTopologicals();
list.add(topological5);
list.add(topological7);
list.add(topological8);
topological3.setTopologicals(list);
list = topological4.getTopologicals();
list.add(topological5);
topological4.setTopologicals(list);
list = topological5.getTopologicals();
list.add(topological7);
topological5.setTopologicals(list);
list = topological6.getTopologicals();
list.add(topological8);
topological6.setTopologicals(list);
list = topological9.getTopologicals();
list.add(topological10);
list.add(topological11);
list.add(topological12);
topological9.setTopologicals(list);
list = topological10.getTopologicals();
list.add(topological12);
topological10.setTopologicals(list);
list = topological11.getTopologicals();
list.add(topological6);
topological11.setTopologicals(list);
//将图中的节点放入列表
List topologicals = new ArrayList();
topologicals.add(topological1);
topologicals.add(topological2);
topologicals.add(topological3);
topologicals.add(topological4);
topologicals.add(topological5);
topologicals.add(topological6);
topologicals.add(topological7);
topologicals.add(topological8);
topologicals.add(topological9);
topologicals.add(topological10);
topologicals.add(topological11);
topologicals.add(topological12);
//定义一个列表来存放入度为零的节点
List topologicalListForReturn = new ArrayList();
int i = 0;
while(i++ <= V_COUNT) {
for(Topological each : topologicals) {
//判断一下是否已经在入度为0的列表中
//如果是,则返回,判断下一个
if(topologicalListForReturn.contains(each)) {
continue;
}
if(each.getIndegree() == 0) {
for(Topological topological : each.getTopologicals()) {
topological.setIndegree(topological.getIndegree() - 1);
}
topologicalListForReturn.add(each);
break;
}
}
}
//如果入度为0的节点数少于图总节点数,则存在环
if(topologicalListForReturn.size() < topologicals.size()) {
System.out.println("此图存在环");
}else {
for(Topological each : topologicalListForReturn) {
System.out.print(each.getName() + " ");
}
}
}
}
总结:入度为0的顶点即为没有前驱的顶点,删除顶点及以它为尾的弧的操作,则可换成以弧头顶点的入度减1来实现。