当前位置: 首页 > news >正文

拓扑排序详解

1. 什么是拓扑排序?

拓扑排序是对有向无环图(DAG)的顶点进行线性排序,使得:

  • 对于任意一条边 u → vu 在排序中总是位于 v 的前面。

示例应用

  • 课程安排(先修课程在前)

  • 任务调度(依赖任务在前)

  • 编译顺序(被依赖的库先编译)


2. 图解拓扑排序

示例图

     5 → 0 ← 4↓       ↓2 → 3 → 1
1. 图的邻接表表示
0: []
1: []
2: [3]
3: [1]
4: [0, 1]
5: [0, 2]
2. 入度计算
节点 0: 2 (来自 5→0 和 4→0)
节点 1: 2 (来自 4→1 和 3→1)
节点 2: 1 (来自 5→2)
节点 3: 1 (来自 2→3)
节点 4: 0
节点 5: 0
3. 拓扑排序步骤(Kahn算法)
步骤队列当前节点操作更新后的入度拓扑序列
1[4, 5]-初始队列(入度=0的节点)--
2[5]4删除 4→0, 4→1in[0]=1, in[1]=1[4]
3[]5删除 5→0, 5→2in[0]=0, in[2]=0[4,5]
4[0, 2]-0和2入队--
5[2]00无出边-[4,5,0]
6[]2删除 2→3in[3]=0[4,5,0,2]
7[3]-3入队--
8[]3删除 3→1in[1]=0[4,5,0,2,3]
9[1]-1入队--
10[]11无出边-[4,5,0,2,3,1]

最终拓扑序列[4, 5, 0, 2, 3, 1]

3.代码

/*拓扑序列对于图中的每一条有向边 (u → v),节点 u 在排序中总是位于 v 的前面只有无环的有向图才存在拓扑序列(因为环会导致循环依赖,无法排序)有向无环图也叫拓扑图入度:有多少边指向自己出度:有多少边从自己这出去的
*/#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define N 100010int n, m;						//节点数,边数
int h[N],e[N], ne[N], idx;		//图的邻接表存储
int d[N];						//入度数组
int q[N];						//队列(通过数组模拟)//添加有向边a -> b
void add(int a, int b)
{e[idx] = b;ne[idx] = h[a];h[a] = idx++;
}//拓扑排序
bool topsort()
{int hh, tt = -1;	//队列指针(队头,队尾)//初始化队列,将所有入度为0的节点入队for (int i = 1;i <= n;i++){if (!d[i])q[++tt] = i;}while (hh <= tt){int t = q[hh++];	//取出队首顶点//遍历该顶点的所有邻接顶点for (int i = h[t];i != -1;i = ne[i]){int j = e[i];	//邻接顶点jif (--d[j] == 0)	//j的入度减1,若为0则入队q[++tt] = j;}}//判断是否所有顶点都入队过return tt == n - 1;
}int main()
{scanf("%d%d", &n, &m);memset(h, -1, sizeof(h));//读入边并构建图while(m--){int a, b;scanf("%d%d", &a, &b);add(a, b);		//b的入度增加d[b]++;}if (!topsort())		//无法拓扑排序(有环)puts("-1");else{//输出拓扑序列for (int i = 0;i < n;i++)printf("%d ", q[i]);puts("");	//puts自动换行}return 0;
}

http://www.xdnf.cn/news/421651.html

相关文章:

  • H5S 视频监控AWS S3 对象存储
  • BGP实验练习2
  • Github 2025-05-13 Python开源项目日报 Top10
  • 从零开始:使用 Vue-ECharts 实现数据可视化图表功能
  • 详解Windows(十一)——网络连接设置
  • 解锁ozon运营新路径:自养号测评技术如何实现降本增效
  • CSS结构性伪类、UI伪类与动态伪类全解析:从文档结构到交互状态的精准选择
  • 【Flask全栈开发指南】从零构建企业级Web应用
  • Vue3+uniapp 封装axios
  • 《猜拳游戏》
  • 深入学习Zookeeper的知识体系
  • 软件测试服务公司分享:国产化适配测试的重要性和关键要素
  • 如何在 CentOS 7 虚拟机上配置静态 IP 地址并保持重启后 SSH 连接
  • ios remote debut proxy 怎么开启手机端调试和inspect
  • C++ string数据查找、string数据替换、string子串获取
  • Rollup入门与进阶:为现代Web应用构建超小的打包文件
  • 【23种设计模式】分类结构有哪些?
  • Java——集合基础
  • OpenCV中的光流估计方法详解
  • 前端面试每日三题 - Day 33
  • 深入理解BLP安全模型:信息安全中的“守密者”
  • win部署Jenkins 自动化部署发布后端项目
  • 文件操作: File 类的用法和 InputStream, OutputStream 的用法
  • 构建媲美 ChatGPT 的 AI 交互界面—OpenWebUI
  • 大模型分布式光伏功率预测实现详解
  • Linux—进度条实现
  • 开源网络地图可视化第六章学习指南
  • 【unity游戏开发——编辑器扩展】使用MenuItem自定义菜单栏拓展
  • 【ArcGIS】根据shp范围生成系列等距点:范围外等距点+渔网点(Python全代码)
  • Android之横向滑动列表