初始化以及原理
拓扑排序基于一个有向无环图构成,当B依赖A,A先B执行的时候,我们画一条A–>B的边。如下代码:
1 | public class Graph { |
排序
有俩种排序算法Kahn算法
Kahn排序
采用贪心算法思想。
- 因为图的关系A–>B,A先执行,所以我们统计每个顶点的入度,凡是入度为0的说明没有依赖应该他先执行;
- 将顶点放到结果执行序列后。将该顶点从图中删除,即该顶点所到达的顶点的入度都-1,如果到0放到执行结果集中;
- 重复上一步直到所有的顶点都在执行序列中。
1 | public void topoSortByKahn() { |
DFS
采用图的深度遍历法
- 制造逆邻接表
- 遍历所有的顶点,如果遇到
1 | //深度优先遍历 |
时间复杂度
kahn复杂度是O(v+e),所有的顶点和边都访问了一次
dfs复杂度是O(v+e),所有的顶点和边都访问了一次
引申
如果A先于B执行我们的边是 A–>B,反过来A<–B,代码是否能正常执行?
答:不能,结果相反的结果,kahn:在算法中A–>B所以A的入度为0,这个入度为0很类似哨兵一样的机制,可以很方便的计入到执行结果中,并且可以一次减少入度。反之,我们入度为0的就变成了最后的数组,如果修改,需要统计出度凡是从出度为0的就是没有依赖的最先执行的,同时简历逆邻接表,在打印完出度为0的数据后在逆邻接表中循环递减出度同时输出,见下方代码。DFS:这个很简单,接别用逆邻接表了。
1 | public void topoSortByKahn() { |