拓扑排序——C语言

news2025/1/11 22:56:01

        拓扑排序(Topological Sorting)是一种用于有向无环图(DAG)的排序算法,其输出是图中所有顶点的线性排序,使得对于每条有向边 (u, v),顶点 u 在 v 之前出现。拓扑排序确定了项目网络图中的起始事件和终止事件,也就是顶点的执行顺序。

        因为是有向无环图,所以拓扑排序的作用其实就是把先发生的排序在前面,后发生的排序到后面。

例如现在我们有一个有向无环图:

        我们可以发现,先发生的是入度为0的顶点,也就是没有边指向的顶点,此时该顶点不需要考虑自己的前驱是否发生完,所以是先发生的顶点,例如顶点 0 和顶点 5 ,这时我们取出这两个顶点,证明已经发生完。

        此时只在考虑谁的入度为0,此时顶点 3 和顶点 2 的入度都为0,所以取出这两个顶点,最后只剩下顶点 1 和顶点 4 。

那么我们该如何实现这个过程呢,首先要注意边数组的输入:

        这里,1 表示该顶点指向另一个顶点,0 则表示没有边。

接下来我们来思考一下代码的思路:

1.计算每个顶点的入度,
2.如果入度为 0 ,记录该顶点,输出。
3.拿到入度为 0 的顶点,并且把该顶点的边都删除掉。
4.重新计算入度,重复第2步,第3步操作。

        这里我们如果要记录该顶点,可以使用队列或者栈,都可以,就拿一开始入度为0的顶点 0 和顶点 5 来说,队列的话会输出 0 5,而栈会输出 5 0 ,两者都可以,这里用栈举例子。

首先是入度数组的初始化:

    int* inDegrees = (int*)malloc(sizeof(int) * G->vexsNum);
	for (int i = 0; i < G->vexsNum; i++) {
		inDegrees[i] = 0;
	}
	for (int i = 0; i < G->vexsNum; i++) {
		for (int j = 0; j < G->vexsNum; j++) {
			if (G->arcs[i][j]) {
				inDegrees[j]++;
			}
		}
	}

if (G->arcs[i][j]) inDegrees[j]++;也就是如果有指向该顶点的边,该顶点的入度就加1。

接下来后三步操作:

	for (int i = 0; i < G->vexsNum; i++) {
		if (inDegrees[i] == 0) {
			StackPush(S, i);
		}
	}
	while (!IsEmpty(S)) {
		int index = StackPop(S);
		printf("%c ", G->vexs[index]);
		for (int i = 0; i < G->vexsNum; i++) {
			if (G->arcs[index][i]) {
				inDegrees[i]--;
				if (inDegrees[i] == 0) {
					StackPush(S, i);
				}
			}
		}
	}

        首先第一个for循环是让入度为0的顶点入栈,然后while循环,出栈拿到入度为0的顶点序号index,接着如果该顶点有指向其他顶点的边 if (G->arcs[index][i]) ,那么就让其他顶点的入度减1,最后再判断一下,如果更新后的入度数组有为 0 的,就将该数组入栈,继续循环。

把两部分组合起来:

void toposort(Graph* G,StackNode* S) {
	int* inDegrees = (int*)malloc(sizeof(int) * G->vexsNum);
	for (int i = 0; i < G->vexsNum; i++) {
		inDegrees[i] = 0;
	}
	for (int i = 0; i < G->vexsNum; i++) {
		for (int j = 0; j < G->vexsNum; j++) {
			if (G->arcs[i][j]) {
				inDegrees[j]++;
			}
		}
	}
	for (int i = 0; i < G->vexsNum; i++) {
		if (inDegrees[i] == 0) {
			StackPush(S, i);
		}
	}
	while (!IsEmpty(S)) {
		int index = StackPop(S);
		printf("%c ", G->vexs[index]);
		for (int i = 0; i < G->vexsNum; i++) {
			if (G->arcs[index][i]) {
				inDegrees[i]--;
				if (inDegrees[i] == 0) {
					StackPush(S, i);
				}
			}
		}
	}
}

这就是文章的全部内容了,希望对你有所帮助,如有错误欢迎评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1854454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式中逻辑分析仪与示波器的基本原理

大家好,今天主要给大家分享一下,嵌入式中如何使用逻辑分析仪和示波器的方法,希望对大家有所帮助。 https://dreamsourcelab.cn/ 第一:什么是逻辑分析仪 是否遇到使用示波器分析数字电路的冏境:深度不够,时间太短,无法抓到想要的波形,没有协议内容解析? 逻辑分析仪…

深度学习11-13

1.神经元的个数对结果的影响&#xff1a; &#xff08;http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html&#xff09; &#xff08;1&#xff09;神经元3个的时候 &#xff08;2&#xff09;神经元是10个的时候 神经元个数越多&#xff0c;可能会产生…

注意 llamaIndex 中 Chroma 的坑!

llamaIndex 做索引是默认存在内存中&#xff0c;由于索引需要通过网络调用 API&#xff0c;而且索引是比较耗时的操作&#xff0c;为了避免每次都进行索引&#xff0c;使用向量数据库进行 Embedding 存储以提高效率。首先将 Document 解析成 Node&#xff0c;索引时调用 Embedd…

解析PDF文件中的图片为文本

解析PDF文件中的图片为文本 1 介绍 解析PDF文件中的图片&#xff0c;由两种思路&#xff0c;一种是自己读取PDF文件中的图片&#xff0c;然后用OCR解析&#xff0c;例如&#xff1a;使用PyMuPDF读取pdf文件&#xff0c;再用PaddleOCR或者Tesseract-OCR识别文字。另一种使用第…

小鹏汽车2025冲刺类L4智驾,挑战与机遇并存

随着科技的飞速发展&#xff0c;智能驾驶已成为汽车行业的前沿领域。近日&#xff0c;小鹏汽车在AI DAY上宣布国内首个量产上车的端到端大模型&#xff0c;这一创新举措无疑为智能驾驶的发展注入了新的活力。然而&#xff0c;在迈向2025年实现类L4级智能驾驶的道路上&#xff0…

DHCP原理1-单个局域网出现多个DHCP服务器会发生什么

1. 背景 DHCP全称是Dynamic Host Configuration Protocol。其协议标准是RFC1541&#xff08;已被RFC2131取代&#xff09;&#xff0c;主要实现服务器向客户端动态分配IP地址&#xff08;如IP地址、子网掩码、网关、DNS&#xff09;和配置信息。其系统架构是标准的C/S架构。RFC…

运算放大器(运放)低通滤波反相放大器电路和积分器电路

低通滤波反相放大器电路 运放积分器电路请访问下行链接 运算放大器(运放)积分器电路 设计目标 输入ViMin输入ViMax输出VoMin输出VoMaxBW&#xff1a;fp电源Vee电源Vcc–0.1V0.1V–2V2V2kHz–2.5V2.5V 设计说明 这款可调式低通反相放大器电路可将信号电平放大 26dB 或 20V/…

算是一些Transformer学习当中的重点内容

一、基础概念 Transformer是一种神经网络结构&#xff0c;由Vaswani等人在2017年的论文Attentions All YouNeed”中提出&#xff0c;用于处理机器翻译、语言建模和文本生成等自然语言处理任务。Transformer同样是encoder-decoder的结构&#xff0c;只不过这里的“encoder”和“…

OpenCV机器学习-人脸识别

一 基本概念 1 计算机视觉与机器学习的关系 计算机视觉是机器学习的一种应用&#xff0c;而且是最有价的应用。 2 人脸识别 哈尔(haar)级联方法 Harr是专门为解决人脸识别而推出的&#xff1b; 在深度学习还不流行时&#xff0c;Harr已可以商用&#xff1b; 深度学习方法&am…

thrift接口调用工具

写了一个thrift接口调用工具 导入thrift文件就可以直接调用相应接口 工具会根据thrift文件中接口的参数名&#xff0c;参数类型&#xff0c;返回值等等&#xff0c;自动生成接口参数&#xff0c;和结果json化显示。 https://github.com/HuaGouFdog/Fdog-Kit

C++初学者指南第一步---14.函数调用机制

C初学者指南第一步—14.函数调用机制 文章目录 C初学者指南第一步---14.函数调用机制1.记住&#xff1a;内存的结构2.函数调用是如何工作的3. 不要引用局部变量4. 常见编译器优化5. Inlining内联 1.记住&#xff1a;内存的结构 堆&#xff08;自由存储&#xff09; 用于动态存…

鸿蒙开发系统基础能力:【@ohos.hiAppEvent (应用打点)】

应用打点 本模块提供了应用事件打点能力&#xff0c;包括对打点数据的落盘&#xff0c;以及对打点功能的管理配置。 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import hiAppEve…

英伟达下一代DLSS或利用人工智能

英伟达的黄仁勋在2024年Computex展会上的问答环节中&#xff0c;提前透露了公司未来几代深度学习超采样&#xff08;DLSS&#xff09;技术的发展方向。在回答有关DLSS的问题时&#xff0c;黄仁勋表示&#xff0c;未来我们将看到通过纯粹的人工智能生成的纹理和对象。他还提到&a…

通过ESP32读取I2C温湿度传感器项目:协议与代码实例

简介 在本项目中&#xff0c;我们将使用ESP32开发板读取I2C温湿度传感器的数据。我们将详细介绍I2C协议&#xff0c;并提供图文并茂的代码实例&#xff0c;帮助你快速上手。 项目流程 选择硬件&#xff1a;ESP32开发板、I2C温湿度传感器&#xff08;如DHT12、HTU21D、SHT30等&a…

yii2 ActiveForm使用技巧

持续更新&#xff1a; 1、搜索输入框&#xff1a;form-inline <?php $form ActiveForm::begin([action > [index],method > get,options > [class > form-inline] &#xff08;增加此行代码&#xff09; ]); ?>

虚拟现实环境下的远程教育和智能评估系统(十三)

管理/教师端前端工作汇总education-admin&#xff1a; 首先是登录注册页面的展示 管理员 首页 管理员登录后的首页如下图所示 管理员拥有所有的权限 课程管理 1、可以查看、修改、增添、删除课程列表内容 2、可以对课程资源进行操作 3、可以对课程的类别信息进行管理&…

【嵌入式开发】STM32+USB的快速开发

目录 一、概述 二、STM32+USB开发流程 2.1 建立新的工程 2.2 系统配置 2.3 时钟配置 2.4 操作系统 2.5 选择USB配置 2.6 在USB_HOST中选择支持的子类(class) 2.7 Clock 配置 三、注意事项 3.1 应用驱动配置 3.2 上电调试基础工作 一、概述 USB作为大家耳熟能详的…

Spdlog日志库的安装配置与源码解析(Linux)

为什么使用日志库而不是控制台输出&#xff1f; 日志库通常提供了更丰富的功能&#xff0c;比如可以设置日志输出级别、输出到不同的目标&#xff08;比如控制台、文件、网络等&#xff09;&#xff0c;以及格式化输出等。 使用日志库可以使代码更易于维护。通过统一的日志接口…

【web2】jquary,bootstrap,vue

文章目录 1.jquary&#xff1a;选择器1.1 jquery框架引入&#xff1a;$("mydiv") 当成id选择器1.2 jquery版本/对象&#xff1a;$(js对象) -> jquery对象1.3 jquery的页面加载事件&#xff1a;$ 想象成 window.onload 1.4 jquery的基本选择器&#xff1a;$()里内容…

计算机网络知识点汇总(三)

1.2 计算机网络体系结构与参考模型 1.2.1 计算机网络分层结构 计算机网络的各层及其协议的集合称为网络的体系结构(Architecture)。换言之&#xff0c;计算机网络的体系结构就是这个计算机网络及其所应完成的功能的精确定义。要强调的是&#xff0c;这些功能究竟是用何种硬件…