拓扑排序一个很典型的应用场景,就是我们开发的项目依赖,比如a依赖于b,b依赖于c、d,d依赖于 c、e,那么项目的依赖加载顺序是?肯定不能出现循环依赖,否则就没办法加载成功了。如何决定项目的加载顺序就需要拓扑排序。拓扑排序针对的是无环有向图,生成做事情的顺序,使得所有点的依赖环境都完备,得到所有点。图结构定义参考
/**
* 拓扑排序
* 要求:有向图 无环
* 方法:先找入度为0的点,把该节点及其影响擦掉
* 然后找下一个入度为0的点,直到找到所有入度为0的点,得到一个拓扑排序
*/
public static List<GraphNode> topoSort(Graph graph) {
List<GraphNode> res = new ArrayList<>();
//存储节点的入度信息
HashMap<GraphNode, Integer> inMap = new HashMap<>();
//入度为0的点进队列
Queue<GraphNode> zeroInqueue = new LinkedList<>();
for (GraphNode node : graph.nodes.values()) {
inMap.put(node, node.in);
if (node.in == 0) {
zeroInqueue.offer(node);
}
}
while (!zeroInqueue.isEmpty()) {
GraphNode cur = zeroInqueue.poll();
res.add(cur);
//擦除当前入度为0的点的影响
for (GraphNode next : cur.nexts) {
inMap.put(next, inMap.get(next) - 1);
if (inMap.get(next) == 0) {
//找到了下一个入度为0的点
zeroInqueue.offer(next);
}
}
}
return res;
}