九章算法官网-原文网址
http://www.jiuzhang.com/problem/66/
题目
给一个有向无环图,求出这个有向无环图的拓扑排序结果。
在线测试本题
http://www.lintcode.com/en/problem/topological-sorting/
解答
【背景知识】
拓扑排序问题在我们生产工序或者是建立依赖关系当中有重要的运用。
通常我们所说的拓扑排序是对一个有向无环图的。 所以把一个有向无环图的顶点组成的序列,每个点只出现一次,并且A在序列中排在B的前面图中不存在从B到A的路径的序列叫做这个图的拓扑排序。
一般来说拓扑排序不一定只有一种。 比如这道题拓扑排序就有[0, 1, 2, 3, 4, 5], [0, 2, 3, 1, 5, 4] 等
入度的意思是有向图中,一个点有N个边指向这个点,那么它的入度就是N, 比如题中1的入度就是1,4的入度就是2
出度度的意思是有向图中,一个点有N个边指向其他的点,那么它的出度就是N, 比如题中0的入度就是3,2的入度就是2
【答案】
对于拓扑排序来说, 我们的中心思想是要我们可以找到一个顺序,每一次我们可以进行的工序是现在没有先序依赖的工序,按照这个顺序可以流畅的完成我们的任务。如果从图论的角度来说,实际上是从一个点遍历整个图,并且遍历图的时候,下次可以遍历的点是入度为0的点, 而我们遍历的顺序就是我们所要求的拓扑排序的顺序。
那么我们既然要遍历一个图,那么我们可以用宽度优先的方法,因为宽度优先的方法非常适合通过一点去遍历整个图,只不过对于求拓扑排序的问题,我们宽度优先搜索有一个条件就是每一次只能遍历当前入度为0的点,也就是说宽度优先所有的队列中只能放入入度为0的点,然后每次遍历一个点之后,就更新这个点相邻的点的入度信息,因为遍历了这个点,相当于相邻的点的依赖前序工序减少了1个,也就是相邻点的入度减少了1,如果相邻点中更新后有入度为0的点,那么我们就把相邻点放入到队列当中以便下一次进行访问。
通过这样的方法我们遍历一遍整个图。用O(m),m为图的边数,的时间复杂度就可以求出这个图的拓扑排序解。