拓扑排序是针对有向无环图的一种广度优先遍历顶点的算法,可以将图中所有顶点按照要求的先后顺序排序。当然,拓扑排序本质不是一种排序算法,而是一种遍历图的算法。
在如果存在顶点 u 和顶点 v,要想到达顶点 v,则必须要到达顶点 u 。那么在拓扑排序中,顶点 u 必须处于顶点 v 的前面。
课程表的规划是拓扑排序的经典应用。
· 拓扑排序算法原理
图中的每个顶点都有入度和出度两个属性,入度是指该顶点被多少个顶点指向,出度指该顶点指向了多少个顶点。
1、创建一个队列,队列里存放所有入度为0的节点。
2、每次从队列中弹出一个节点A,记录为已访问。将A的未访问过的相邻节点的入度-1(但这些节点未访问),并将新的入度为0的节点放入队列。
3、重复步骤2,直到队列为空。
不能完成拓扑排序的情况:
1、如果初始状态下,所有节点的入度都为0,说明图中所有顶点都成环,无法完成拓扑排序;
2、如果队列为空后,图中仍存在未访问的节点,说明图中部分顶点成环,无法完成拓扑排序。
拓扑算法本质是广度优先遍历 + 贪心算法,假设最终解为res数组,存储拓扑排序后顶点的顺序。每一个局部最优解是入度为0的顶点,优先访问掉这些顶点放入res中,并生成新的入度为0的未访问顶点,再进入下一个局部状态。
代码实现如下:
测试用例如下: