拓扑排序(Topological Sort)

拓扑排序(Topological Sort)

定义

拓扑排序是对有向无环图(DAG, Directed Acyclic Graph) 中所有节点进行线性排序的算法,使得对于图中每条有向边 u → v,节点 u 在排序结果中都出现在节点 v 之前。

⚠️ 拓扑排序只适用于有向无环图,如果图中存在环,则无法进行拓扑排序。


直观理解

想象一组任务,某些任务必须在其他任务之前完成:

复制代码
穿袜子 → 穿鞋子
穿内衣 → 穿衬衫 → 穿外套
穿裤子 → 穿鞋子

拓扑排序就是找到一个合法的执行顺序,例如:
穿内衣 → 穿袜子 → 穿裤子 → 穿衬衫 → 穿外套 → 穿鞋子


两种经典算法

1. Kahn 算法(BFS 方式)

核心思想:不断移除入度为 0 的节点

python 复制代码
from collections import deque

def topological_sort_kahn(graph, in_degree):
    queue = deque()
    result = []

    # 将所有入度为 0 的节点加入队列
    for node in in_degree:
        if in_degree[node] == 0:
            queue.append(node)

    while queue:
        node = queue.popleft()
        result.append(node)

        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    # 如果结果长度不等于节点数,说明有环
    if len(result) != len(in_degree):
        return []  # 存在环
    return result

步骤:

  1. 计算所有节点的入度
  2. 将入度为 0 的节点入队
  3. 出队一个节点,将其邻居的入度 -1
  4. 若邻居入度变为 0,则入队
  5. 重复直到队列为空

2. DFS 算法(深度优先搜索)

核心思想:DFS 后序遍历,逆序即为拓扑序

python 复制代码
def topological_sort_dfs(graph):
    visited = set()
    stack = []

    def dfs(node):
        visited.add(node)
        for neighbor in graph.get(node, []):
            if neighbor not in visited:
                dfs(neighbor)
        stack.append(node)  # 后序加入

    for node in graph:
        if node not in visited:
            dfs(node)

    return stack[::-1]  # 逆序输出

两种算法对比

特性 Kahn(BFS) DFS
实现方式 迭代 递归
环检测 ✅ 天然支持 需额外标记
时间复杂度 O(V + E) O(V + E)
空间复杂度 O(V) O(V)
结果唯一性 不唯一 不唯一

应用场景

场景 说明
📦 包管理器 npm、pip 解析依赖安装顺序
🏗️ 构建系统 Make、Gradle 确定编译顺序
📚 课程规划 先修课程问题
🔄 任务调度 确定任务执行顺序
🗃️ 数据库 外键约束的表创建顺序

总结

复制代码
拓扑排序 = 对 DAG 节点排序,保证所有边从前指向后
核心性质:有向 + 无环 → 才能拓扑排序
两种算法:Kahn(BFS入度法)/ DFS(后序逆置法)
时间复杂度:O(V + E)
相关推荐
梅雅达编程笔记12 小时前
编程启蒙|Scratch 转 Python 系列第9天:字典/哈希表积木双向对照(AI大模型参数配置表实战)
开发语言·人工智能·python·numpy·pandas
zhz521412 小时前
GIS项目中空间参考转换与MBTiles偏移:问题成因、解法与避坑
python·vue·gis
KaMeidebaby13 小时前
卡梅德生物技术快报|如何制备单克隆抗体:小众禽类靶点单抗制备实操流程:双载体抗原交叉筛选完整工艺记录
人工智能·python·深度学习·算法·机器学习
乱写代码14 小时前
Pydantic学习--BaseModel
python
fu159357456814 小时前
【边缘计算实战】P1:从零搭建边云任务卸载仿真实验台(Python 可复现)
数据库·python·边缘计算
蜡台15 小时前
通过Gradle脚本声明更改Java变量
android·java·开发语言·python·kotlin·gradle·groovy
Larcher15 小时前
当 AI 学会写代码:一个自动生成 React 项目的 Agent 实战
人工智能·设计模式·程序员
智能体与具身智能15 小时前
TVA 本质内涵与核心特征(系列)
人工智能·python·智能体视觉
云雾J视界15 小时前
SST:高频变压器设计实战:铁氧体 vs 纳米晶 vs 非晶,磁性材料怎么选
python·acdc·dab·sst
第一程序员16 小时前
Rust trait 入门:把 AI 客户端抽象成可替换接口
python·rust·github