拓扑排序是基于依赖关系的节点,根据依赖关系而生成的序列。节点和依赖关系往往要生成有向无环图。类似的问题有:穿衣服裤子的先后关系,生成穿衣序列/专业课程与前置课程形成的课程学习序列/代码编译依赖关系形成的编译顺序序列。
解决办法有两种:
- 先a后b则 a->b,数据结构为临接表来描述
- kahn(卡恩)算法
根据邻接表,很容易计算出每个节点的入度。
遍历每个入度,将入度为0的节点,放入队列。
队列不空,循环:
取出队首元素,输出他,然后遍历他的邻接节点,将邻接节点入度-1,如果邻接节点恰好为0,将节点放入队列。
时间复杂度:求入度:O(v+e),循环输出O(v+e)合起来O(v+e)
空间复杂度:入度数组O(v),队列<O(v)
dfs算法: - 深度优先搜索是要一通到底的,所以需要将邻接表返过来,改成逆邻接表。方法:遍历邻接表,对i的每个邻接节点j,都将i加到j的逆邻接表中。
- 图的深度优先搜索不跟树一样:没有根节点,所以要尝试从每个节点都开始一次,自然需要visited数组防止重复。对某个节点深度遍历完之后,再输出。
显然用于拓扑排序的图是不可以成环的。自然拓扑排序算法可以用于检测图中的环。对于kahn算法,极端化思维:如果所有的节点形成大环,那么没有入度为0的节点,也就不会有任何输出。普通思维:如果存在环,总会到一个位置,没有任何节点入度为0。就会少输出节点。如果输出的节点<总结点,意味着存在环。