首页/数据结构/05-graph/拓扑排序 🔗 在 Obsidian 中打开
数据结构 · 05-graph

拓扑排序

难度 ★★★重要度 ★★★★ 考查频率 高题型 选择 / 综合应用 数据结构/图拓扑排序有向无环图DAG
速查
拓扑排序DAG 可行:每步选入度为 0 的顶点输出并删其出边;输出顶点数 < 总数 ⟺ 有环。时间 $O(|V|+|E|)$。

速查

项目
主题拓扑排序
核心概念AOV 网(顶点表示活动),对有向无环图排成线性序列
时间复杂度$O(|V|)$、$O(|V|+|E|)$
难度⭐⭐⭐
重要性⭐⭐⭐⭐

核心概念

一、定义

AOV 网(Activity On Vertex Network):用顶点表示活动,边表示活动的先后关系,是有向无环图(DAG)。

拓扑排序:对 DAG 的顶点进行线性排序,使得对任意有向边 $\langle u,v\rangle$,$u$ 在序列中出现在 $v$ 之前。

二、算法步骤

  1. 选一个入度为 0 的顶点,输出
  2. 删除该顶点及所有出边
  3. 重复,直到:所有顶点输出 ⟹ 排序成功;无入度为 0 但仍有顶点 ⟹ 有环

三、代码实现(邻接表)

bool TopologicalSort(ALGraph G) {
    int indegree[MaxVertexNum];
    SqStack S; InitStack(&S);
    for (int i = 0; i < G.vexnum; i++) {
        indegree[i] = 0;
        ArcNode *p = G.vertices[i].first;
        while (p) { indegree[p->adjvex]++; p = p->next; }
    }
    for (int i = 0; i < G.vexnum; i++)
        if (indegree[i] == 0) Push(&S, i);
    int count = 0;
    while (!StackEmpty(S)) {
        Pop(&S, &v); printf("%d ", v); count++;
        ArcNode *p = G.vertices[v].first;
        while (p) {
            indegree[p->adjvex]--;
            if (indegree[p->adjvex] == 0) Push(&S, p->adjvex);
            p = p->next;
        }
    }
    return (count == G.vexnum);   // false 表示有环
}

时间复杂度 $O(|V|+|E|)$

四、应用

  • 判断有向图是否有环:拓扑排序能否输出所有顶点
  • 求关键路径(AOE 网):拓扑排序求事件最早发生时间,逆拓扑求最迟发生时间

五、拓扑序列不唯一

同一时刻可能有多个入度为 0 的顶点,选择不同导致序列不同;唯一性条件:每个步骤只有一个入度为 0 的顶点可选。

手算示例

例 1:拓扑排序

A → B → D
|       ↑
↓       |
C → E → F

入度:A0, B1, C1, D2, E1, F1。依次选 A→B→→D 等,拓扑序列 A B C E F D(不唯一)。

例 2:判断有环

A → B → C → A

入度:A1, B1, C1,无入度为 0 的顶点 ⟹ 有环!

例 3:所有拓扑序列

A → C   A → D
B → C   B → D

入度:A0, B0, C2, D2。可能序列:A B C D、A B D C、B A C D、B A D C,共 4 种

常见考法

考法 1:拓扑排序手算给出有向图,写出一个拓扑序列。
考法 2:判断有环拓扑排序能否输出所有顶点?
考法 3:拓扑序列计数问有多少种拓扑序列?
考法 4:时间复杂度$O(|V|+|E|)$。

易错点

注意
  1. 每次选入度为 0 的顶点,不是出度为 0
  2. 用栈或队列存放都可以,不影响正确性
  3. 拓扑序列不唯一,除非每步只有一个选择
  4. 有环则无法完成排序,可作为判断环的依据
  5. 删除顶点时更新入度:所有出边对应的邻接点入度减 1

核心结论

属性
适用有向无环图(DAG)
时间$O(|V|+|E|)$
空间$O(|V|)$
应用判断环、求关键路径

记忆卡片

拓扑排序每次选什么顶点?
入度为 0 的顶点。
拓扑排序能判断什么?
有向图是否有环。
拓扑排序的时间复杂度?
$O(|V|+|E|)$。
拓扑序列唯一吗?
一般不唯一。
拓扑排序适用于什么图?
有向无环图(DAG)。
输出顶点数少于总数说明什么?
图中存在环。

交互动画 · Kahn 算法与环检测

依次删去入度为 0 的顶点;卡住时剩余顶点即构成环 A B C D E
点击「播放」观察拓扑排序过程
入度:A=0, B=2, C=1, D=1, E=1

本例中 A、D、E 能正常拓扑排出;B 与 C 互相指向,入度永远无法降到 0,故被标红——这正是“有环”的判定依据。

相关知识点

graph-traversal minimum-spanning-tree shortest-path critical-path mst-and-shortest-path graph-storage-structure

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。