图搜索

拓扑排序

拓扑排序针对的是有向无环图(DAG):节点之间有”必须先做 A 再做 B”的依赖关系,需要给出一个不违反任何依赖的线性顺序。课程先修关系、构建系统的任务编排、make/cargo 依赖图都是这个套路。

Kahn 算法

直觉非常简单:

  1. 统计每个节点的入度(被多少箭头指向)
  2. 入度为 0 的节点没有先修依赖,可以立刻执行 → 放进队列
  3. 每次从队列取一个节点放到输出,并把它指向的所有节点的入度减 1
  4. 谁的入度被减到 0,就也入队
  5. 重复直到队列为空

如果走完后输出长度等于节点数,结果就是一个合法拓扑序;否则说明存在

复杂度

  • 时间:O(V + E) — 每条边只被”消去”一次
  • 空间:O(V)

在动画里看什么

  • 节点圆圈下方的 in:N当前入度,随出队过程下降
  • 浅蓝:在 queue 里等待处理;深蓝:正在被处理;绿色:已经放入输出序列
  • 边的箭头变灰表示这条依赖已经被消化
  • 底部的 queueorder 实时显示队列内容和当前拓扑序