拓扑排序——C语言

        拓扑排序(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.mzph.cn/bicheng/32755.shtml

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

相关文章

c++精解【5】

文章目录 Eigen矩阵元素定义矩阵加法矩阵乘法向量编译时设置大小 poco名言基础 Eigen 矩阵元素定义 定义每个元素值 [ 1 3 2 4 ] \begin{bmatrix} 1& 3 \\2& 4 \end{bmatrix} [12​34​] #include <iostream> #include "f:/learn/eigen-3.4.0/Eigen/Den…

Prompt 写作提示经验:完整格式和技巧

编写prompt以确保输出格式通常需要明确指定您期望的输出结构和内容要求。以下是一些确保输出格式的步骤和技巧&#xff1a; 明确指定格式&#xff1a;在prompt中明确指出您期望的输出格式。例如&#xff0c;如果您需要一个包含标题、子标题和段落的文章&#xff0c;应在prompt中…

大电流一体成型电感CSEB1350系列,助力实现DC-DC转换器小尺寸、高效率

DC-DC转换器 , 转换器 , 科达嘉 DC-DC转换器作为一种电压转换装置&#xff0c;在电子产品、电源系统、工业控制、新能源等领域广泛应用。。。 DC-DC转换器作为一种电压转换装置&#xff0c;在电子产品、电源系统、工业控制、新能源等领域广泛应用。随着各行业用户对DC-DC转换器…

Appium + Python App自动化第一个脚本

今天跟大家讲解一个Appium和Python App自动化的脚本。 【1】打开你的夜神模拟器&#xff08;或者连接你的手机&#xff09; 【2】打开桌面的Appium 【3】下载你要测的App的apk文件&#xff0c;放到桌面 【4】拖动你的apk安装包到夜神模拟器里&#xff0c;然后模拟器会提示你…

redHat9 安装 docker、docker-compose、iptables 过程记录

1. 确认 Linux 版本&#xff1a; cat /etc/redhat-release 我这里显示&#xff1a;Red Hat Enterprise Linux release 9.2 (Plow)2. 准备 docker 离线安装包&#xff1a; 我这里是从阿里云开源镜像站 https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/ 提…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-36图像增广

6 图片增广 import matplotlib.pyplot as plt import numpy as np import torch import torchvision from d2l import torch as d2l from torch import nn from PIL import Image import liliPytorch as lp from torch.utils.data import Dataset, DataLoaderplt.figure(cat)…

B站大模型指令微调入门实战(完整代码),一键打造你的数字分身

前两天&#xff0c;想导出微信聊天记录&#xff0c;于是搞了个小工具。 感兴趣的小伙伴&#xff0c;可以回看&#xff1a; 微信聊天记录导出为电脑文件实操教程&#xff08;附代码&#xff09; 一键获取所有微信聊天记录&#xff08;附PyQT6入门实战&#xff09; 拿到这些数…

yq 配置文件格式转换工具

在现代开发和运维的世界中&#xff0c;处理和转换不同格式的数据文件如 YAML、JSON、XML、CSV 等是日常任务。文件格式的多样性和复杂性常常给开发者带来不小的挑战。在这种情况下&#xff0c;强大的命令行工具能够极大地简化工作流程&#xff0c;本文主要介绍一款基于Go实现处…

docker中mysql突然无法连接设置

参考地址解决&#xff1a;连接不上 docker中的mysql_thinkphp6 连不上 docker mysql-CSDN博客

Python中使用PyQT5库时报错:没有Qt平台插件可以初始化

一、发现问题&#xff1a;无限易pythonGo打开执行的时候报&#xff1a;“没有Qt平台插件可以初始化&#xff0c;请重新安装应用程序。”的错误&#xff0c;点击确定后无限易崩溃闪退。 二、解决问题&#xff1a; 1、重新安装依赖&#xff0c;打开CMD输入pip list&#xff0c;查…

Leetcode3185. 构成整天的下标对数目 II

Every day a Leetcode 题目来源&#xff1a;3185. 构成整天的下标对数目 II 解法1&#xff1a;哈希 本质思路类同经典的“两数之和”。枚举右&#xff0c;用哈希表维护左。 枚举 j&#xff0c;并维护 cnt[x] 表示所有满足 i < j 的下标 i 中&#xff0c;有几个 hours[i]…

初识 SpringMVC,运行配置第一个Spring MVC 程序

1. 初识 SpringMVC&#xff0c;运行配置第一个Spring MVC 程序 文章目录 1. 初识 SpringMVC&#xff0c;运行配置第一个Spring MVC 程序1.1 什么是 MVC 2. Spring MVC 概述2.1 Spring MVC 的作用&#xff1a; 3. 运行配置第一个 Spring MVC 程序3.1 第一步&#xff1a;创建Mave…

c++中log4cplus日志库引用

c中log4cplus日志库引用 源码地址:编译及安装主要能力&#xff1a;使用 log4cplus 的基本步骤和示例代码使用示例&#xff1a;标准使用示例&#xff1a;简洁使用示例&#xff1a;异步模式使用&#xff1a; Log4cplus是一个C的日志库&#xff0c;它提供了灵活的日志记录功能&…

基于CDMA的多用户水下无线光通信(1)——背景介绍

研究生期间做多用户水下无线光通信&#xff08;Underwater Optical Wireless Communication&#xff0c;UOWC&#xff09;&#xff0c;写几篇博客分享一下学的内容。导师给了大方向&#xff0c;让我用直接序列码分多址&#xff08;Direct Sequence Code Division Multiple Acce…

创建指定数值范围的数组

导入numpy import numpy as np 1. 创建指定数值范围的数组 数值范围[1, 12)&#xff0c;步长为2 # start 表示开始值 stop 表示结束值 step 表示步长 n1 np.arange(1,12,2) n1 2. 创建等差的数组 7500-10000&#xff0c;6等分&#xff0c;结束点包含 # linspace: …

塞贝壳效应

塞贝克效应&#xff08;Seebeck effect&#xff09;&#xff0c;通常被称为第一热电效应&#xff0c;是由托马斯约翰塞贝克&#xff08;Thomas Johann Seebeck&#xff09;在1821年发现的一种热电现象。这个效应描述了当两种不同的导体或半导体在它们的接点处有温度差时&#x…

containerd手动配置容器网络

containerd手动配置容器网络 机器详情nerdctl启动一个不带网络的容器获取容器ID、PID与network namespace路径准备bridge插件的执行配置文件通过下面的命令调用bridge插件准备tuning插件文件执行下面的命令调用tuning插件准备portmap插件文件执行下面的命令调用portmap插件删除…

SFF1006A-ASEMI无人机专用SFF1006A

编辑&#xff1a;ll SFF1006A-ASEMI无人机专用SFF1006A 型号&#xff1a;SFF1006A 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;10A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;600V 最大…

富文本编辑器CKEditor

介绍 富文本编辑器不同于文本编辑器,它提供类似于 Microsoft Word 的编辑功能 在Django中,有可以现成的富文本三方模块django-ckeditor,具体安排方式: pip install django-ckeditor==6.5.1官网:Django CKEditor — Django CKEditor 6.7.0 documentation 使用方式 创建项…

QT事件处理系统之三:子类化QPushButton后,对事件进行相应处理后,自定义按钮无法发出clicked信号的问题

1、信号槽绑定 如下,Widget中进行了SelfButton按钮的信号槽绑定。 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi