图论入门算法:拓扑排序(C++)
上文中我们了解了图的遍历(DFS/BFS), 本节我们来学习拓扑排序.
在图论中, 拓扑排序(Topological Sorting)是对一个有向无环图(Directed Acyclic Graph, DAG)的所有顶点进行排序的一种算法, 使得如果存在一条从顶点 u 到顶点 v 的有向边 (u, v) , 那么在排序后的序列中, u 一定在 v 之前.
环境要求
本文所用样例在Windows 11以及Ubuntu 24.04上面编译通过.
- Windows: 使用[Visual Studio],
- Ubuntu: 使用 Clang 18.1.3. (Ubuntu 24.04 系统安装版本)
- GCC 无法编译直接本项目代码, 因为本文代码使用了 C++20 Module, 而 GCC 对此支持不完整.
关于 Module 的更多信息, 请参考我之前的博客: CMake 构建 C++20 Module 实例(使用 MSVC)
本项目工程目录: 图论代码
适用场景
拓扑排序适用于需要确定一系列任务的执行顺序, 且任务之间存在依赖关系的场景. 下图是是一个示例图, 其中顶点代表任务, 有向边代表依赖(A -> B 意味着A 需要在 B 之前完成). 拓扑排序就是给出任务能够完成的先后顺序.

算法实现
常见的拓扑排序算法有两种: Kahn 算法和深度优先搜索(DFS)算法.
Kahn 算法
- 统计每个顶点的入度(即指向该顶点的边的数量).
- 将所有入度为 0 的顶点加入队列中.
- 从队列中取出一个顶点, 将其输出, 并将该顶点的所有邻接顶点的入度减 1.
- 如果某个邻接顶点的入度变为 0, 则将其加入队列中.
- 重复步骤 3 和 4, 直到队列为空.
- 如果输出的顶点数量小于图中的顶点总数, 则说明图中存在环, 无法进行拓扑排序.
过程步骤如图:
- 起初, 入度为 0 的顶点为
A,F. 我们可以弹出A和F中的任意一个. 这里假设我们先弹出A.

- 弹出
A后, 边线A -> B和A -> C被弹出, 并且入度B和C分别减 1, 此时状态如图所示. 接下来我们要弹出F.

- 弹出
F后, 边线F -> C被弹出, 并且入度C减 1, 此时状态如图所示. 接下来我们弹出B.

- 弹出
B后, 边线B -> D被弹出, 并且入度D减 1, 此时状态如图所示. 接下来我们弹出C.

- 弹出
C后, 边线C -> D被弹出, 并且入度D减 1, 此时状态如图所示. 接下来我们弹出D.

- 弹出
D后, 边线D -> E被弹出, 并且入度E减 1, 此时状态如图所示. 接下来我们弹出E.

- 弹出
E后, 队列为空, 算法结束.
代码实现
class TopologicalSortKahn {public:explicit TopologicalSortKahn(const AdjList& graph) : graph_(graph) {if (!graph_.Directed()) {throw std::invalid_argument("Graph must be directed for topological sorting.");}}std::vector<相关文章:
图论入门算法:拓扑排序(C++)
上文中我们了解了图的遍历(DFS/BFS), 本节我们来学习拓扑排序. 在图论中, 拓扑排序(Topological Sorting)是对一个有向无环图(Directed Acyclic Graph, DAG)的所有顶点进行排序的一种算法, 使得如果存在一条从顶点 u 到顶点 v 的有向边 (u, v) , 那么在排序后的序列中, u 一定…...
【CXX】2 CXX blobstore客户端说明
本示例演示了一个调用blobstore服务的C客户端的Rust应用程序。事实上,我们会看到两个方向的调用:Rust到C以及C到Rust。对于您自己的用例,您可能只需要其中一个方向。 示例中涉及的所有代码都显示在此页面上,但它也以可运行的形式提…...
HTTP相关面试题
HTTP/1.1、HTTP/2、HTTP/3 演变 HTTP/1.1 相比 HTTP/1.0 提高了什么性能? HTTP/1.1 相⽐ HTTP/1.0 性能上的改进: 使⽤长连接的⽅式改善了 HTTP/1.0 短连接造成的性能开销。⽀持管道(pipeline)网络传输,只要第⼀个请…...
关于XML映射器的基本问题
前言 XML 映射器是 MyBatis 中用于定义 SQL 语句及其与 Java 对象映射关系的 XML 文件。它通过 XML 配置将数据库操作与 Java 代码分离,使 SQL 语句更易维护和管理。 主要作用 定义 SQL 语句:在 XML 中编写 SQL 查询、插入、更新和删除操作。 映射结果…...
【MyBatis】预编译SQL与即时SQL
目录 1. 以基本类型参数为例测试#{ }与${ }传递参数的区别 1.1 参数为Integer类型 1.2 参数为String类型 2. 使用#{ }传参存在的问题 2.1 参数为排序方式 2.2 模糊查询 3. 使用${ }传参存在的问题 3.1 SQL注入 3.2 对比#{ } 与 ${ }在SQL注入方面存在的问题 3.3 预编译…...
Python--正则表达式
1. 日志打印与终端颜色控制 1.1 使用 loguru 打印日志 from loguru import loggerlogger.debug("调试信息") logger.info("普通信息") logger.warning("警告信息") logger.error("错误信息") logger.success("成功信息"…...
【java面试】线程篇
1.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。 2.线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任…...
分布式光纤传感:为生活编织“感知密网”
分布式光纤测温技术虽以工业场景为核心,但其衍生的安全效益已逐步渗透至日常生活。 分布式光纤测温技术(DTS)作为一种先进的线型温度监测手段,近年来在多个领域展现了其独特的优势。虽然其核心应用场景主要集中在工业、能源和基础…...
cmake Qt Mingw windows构建
今天教大家怎么在windows构建qt应用使用cmd命令行,而不是一键通过QtCreator一键构建。首先我们用qtcreator创建一个模板程序(PS:记得在安装qt时要悬着mingw套件,如果安装太慢可以换源) 输入以下的命令: mkdir build …...
无人机信号调制技术原理
一、调制技术的必要性 频谱搬移:将低频的基带信号搬移到高频的载波上,便于天线辐射和传播。 信道复用: 利用不同的载波频率或调制方式,实现多路信号同时传输,提高信道利用率。 抗干扰: 通过选择合适的调…...
书评与笔记:《如何有效报告Bug》
文章目录 书评笔记核心原则1. 首要目标:让程序员亲眼看到问题2. 次要目标:详细描述问题3. 保持冷静,避免误操作4. 提供额外信息5. 清晰、准确地表达 实用建议不要自作聪明地诊断问题类比:看医生时的症状描述程序员的心理 总结 原文…...
3.【线性代数】——矩阵乘法和逆矩阵
三 矩阵乘法和逆矩阵 1. 矩阵乘法1.1 常规方法1.2 列向量组合1.3 行向量组合1.4 单行和单列的乘积和1.5 块乘法 2. 逆矩阵2.1 逆矩阵的定义2.2 奇异矩阵2.3 Gauss-Jordan 求逆矩阵2.3.1 求逆矩阵 ⟺ \Longleftrightarrow ⟺解方程组2.3.2 Gauss-Jordan求逆矩阵 1. 矩阵乘法 1.…...
[JVM篇]虚拟机性能监控、故障处理工具
虚拟机性能监控、故障处理工具 基础故障处理工具 jps(JVM Peocess Status Tool - 虚拟机进程状况工具) jstat(JVM Statistics Monitoring Too - 虚拟机统计信息监视工具) jinfo( Configuration info for Java - Java配置信息工具) jmap(Memory Map for…...
UniApp 中 margin 和 padding 属性的使用详解
margin 属性的作用与使用 margin 属性用于设置元素的外边距,也就是元素与其他元素之间的距离。它可以分别设置元素四个方向(上、右、下、左)的外边距,也支持使用简写形式来一次性设置多个方向的外边距。 <template><view…...
`fi` 是 Bash 脚本中用来结束 `if` 条件语句块的关键字
fi 是 Bash 脚本中 if 语句的结束标志,它用于结束一个 if 块。与其他编程语言(如 C、Java)中的 } 不同,Bash 使用 fi 来标识条件语句的结束。 语法示例: if [ condition ]; then# 如果条件为真时执行的代码echo &quo…...
cap2:1000分类的ResNet的TensorRT部署指南(python版)
《TensorRT全流程部署指南》专栏文章目录: cap1:TensorRT介绍及CUDA环境安装cap2:1000分类的ResNet的TensorRT部署指南(python版)cap3:自定义数据集训练ResNet的TensorRT部署指南(python版&…...
每日一题——把数字翻译成字符串
把数字翻译成字符串 题目描述示例示例1示例2 题解动态规划代码实现复杂度分析 总结 题目描述 有一种将字母编码成数字的方式:‘a’->1, ‘b’->2, … , ‘z’->26。 现在给一串数字,返回有多少种可能的译码结果。 数据范围:字符串…...
我们来学HTTP/TCP -- 三次握手?
三次握手 题记三次呼叫结语 题记 来,我们来演示下川普王和普京帝会面了 哎呦!你好你好,握手…哎嗨!侬好侬好,握手…欧嘿呦玛斯,握手… 抓狂啊!作孽啊!!! 不说人话啊! 关键的是,“三…...
多媒体软件安全与授权新范例,用 CodeMeter 实现安全、高效的软件许可管理
背景概述 Reason Studios 成立于 1994 年,总部位于瑞典斯德哥尔摩,是全球领先的音乐制作软件开发商。凭借创新的软件产品和行业标准技术,如 ReWire 和 REX 文件格式,Reason Studios 为全球专业音乐人和业余爱好者提供了一系列高质…...
SQL复习
SQL复习 MySQL MySQL MySQL有什么特点? MySQL 不支持全外连接。 安装 数据类型 MySQL中的数据类型分为哪些? MySQL中的数据类型主要分为三大类:数值类型、字符串类型、日期时间类型。 其中, 数值类型又分为七种:T…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
