拓扑排序笔记

这段代码通过拓扑排序对有向无环图进行排序。它创建了一个图结构,其中包含节点、邻接表和入度数组。然后,通过输入添加了一些边,创建了图的结构。接着,使用拓扑排序算法对图进行排序,并将排序后的结果打印输出。

首先,它定义了Node结构来表示图中的节点,包含了节点值和指向下一个节点的指针。然后,Graph结构表示整个图,包含了邻接表、入度数组以及节点数量。

createNode函数中,它创建了一个新的节点,并为其分配内存。createGraph函数用于创建一个图结构,并初始化邻接表和入度数组。

addEdge函数用于在图中添加边。对于有向图中的每条边,它在adjList中的源节点位置创建一个新节点,并将其添加到邻接表的头部,并且同时更新了目标节点的入度。

enqueuedequeue函数是用于实现队列的基本操作,用于在拓扑排序算法中管理节点的顺序。

topologicalSort函数实现了拓扑排序算法。首先,它找到入度为0的节点,并将其加入队列。接着,它开始迭代处理队列中的节点,将其邻接节点的入度减1,并将入度减为0的邻接节点加入队列。这个过程一直持续到队列为空。如果最后排序的节点数和图的节点数不一致,说明图中存在环路,这种情况下会返回NULL。

main函数中,它接收用户的输入并创建图,然后进行拓扑排序。最后,根据排序结果输出结果。

这段代码执行过程中,对节点编号进行了处理,使得输出结果中的节点编号从1开始,并按照拓扑排序的顺序输出。

#include <stdio.h>
#include <stdlib.h>#define MAX_NODES 200000struct Node {int value;struct Node* next;
};struct Graph {struct Node* adjList[MAX_NODES];int inDegree[MAX_NODES];int numNodes;
};struct Node* createNode(int value) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->value = value;newNode->next = NULL;return newNode;
}struct Graph* createGraph(int numNodes) {struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));graph->numNodes = numNodes;for (int i = 0; i < numNodes; ++i) {graph->adjList[i] = NULL;graph->inDegree[i] = 0;}return graph;
}void addEdge(struct Graph* graph, int src, int dest) {struct Node* newNode = createNode(dest);
//让目标那条边直接成为graph->adjList[src]。这样一来每个graph->adjList[src]就会是指向的边
//当时候入度为0的节点跳出时,就可以 int adjNode = temp->value; graph->inDegree[adjNode]--;
//直接让graph->adjList[src]指向的入度减一并遍历,就很简单了newNode->next = graph->adjList[src];graph->adjList[src] = newNode;
//这里要注意,dest是被指向的边,所以它的入度要加一graph->inDegree[dest]++;
}void enqueue(int queue[], int* rear, int node) {queue[(*rear)++] = node;
}int dequeue(int queue[], int* front) {return queue[(*front)++];
}int* topologicalSort(struct Graph* graph) {int* result = (int*)malloc(graph->numNodes * sizeof(int));int front = 0, rear = 0;int queue[MAX_NODES];int idx = 0;for (int i = 0; i < graph->numNodes; ++i) {if (graph->inDegree[i] == 0) {enqueue(queue, &rear, i);}}while (front != rear) {int currentNode = dequeue(queue, &front);result[idx++] = currentNode;struct Node* temp = graph->adjList[currentNode];while (temp != NULL) {int adjNode = temp->value;graph->inDegree[adjNode]--;if (graph->inDegree[adjNode] == 0) {enqueue(queue, &rear, adjNode);}temp = temp->next;}}if (idx != graph->numNodes) {free(result);return NULL; // Graph contains cycle}return result;
}int main() {int n, m;scanf("%d %d", &n, &m);struct Graph* graph = createGraph(n);for (int i = 0; i < m; ++i) {int u, v;scanf("%d %d", &u, &v);
//这里u - 1, v - 1其实是为了满足数组从索引0开始存储,因为节点是1,2,3...这样算的,
//而我想从0,1,2....
//输出的时候要加1回来addEdge(graph, u - 1, v - 1);}int* result = topologicalSort(graph);if (result == NULL) {printf("-1\n");} else {for (int i = 0; i < n; ++i) {if (i == n - 1) {printf("%d", result[i] + 1);//加1回来} else {printf("%d ", result[i] + 1);}}free(result);}return 0;
}

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

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

相关文章

C++如何获取随机浮点数

在C中&#xff0c;可以使用标准库中的<random>头文件来生成随机浮点数。以下是一个简单的例子&#xff1a; #include <iostream> #include <random>int main() {// 创建一个随机数生成器对象std::random_device rd;std::mt19937 gen(rd());// 创建一个均匀分…

使用FFmpeg进行录屏

不用下载那些录屏软件&#xff0c;安装了FFmpeg的话&#xff0c;直接实现 使用FFmpeg进行屏幕录制可以通过以下步骤实现&#xff1a; 安装FFmpeg&#xff1a;首先需要在您的系统上安装FFmpeg。可以通过包管理器&#xff08;如apt、yum等&#xff09;或从官方网站下载并编译安装…

openGauss学习笔记-176 openGauss 数据库运维-实例主备切换

文章目录 openGauss学习笔记-176 openGauss 数据库运维-实例主备切换176.1 操作场景176.2 操作步骤176.3 示例176.4 错误排查176.5 异常处理 openGauss学习笔记-176 openGauss 数据库运维-实例主备切换 176.1 操作场景 openGauss在运行过程中&#xff0c;数据库管理员可能需要…

linux卸载小皮面板phpstudy教程

千万不要直接删文件夹! 千万不要直接删文件夹! 千万不要直接删文件夹! 我就是按照网上搜索的教程,直接删了,然后 系统就不停的崩溃 生成这种文件: -rw------- 1 root root 223M Dec 28 22:36 core.31544 -rw------- 1 root root 223M Dec 28 18:04…

基于elemen二次封装弹窗组件

效果&#xff1a; 一、自定义内容类型弹窗 <!-- title&#xff1a;对话框的标题confirmLoading&#xff1a;当前是否处于提交中titleCenter&#xff1a;对话框标题居中方式footerCenter&#xff1a;底部按钮的对其方式visible&#xff1a;是否显示弹窗width&#xff1a;设置…

【机器学习】Boosting算法-AdaBoost算法

一、AdaBoost理论 随机森林与AdaBoost算法的比较 AdaBoost算法 AdaBoost模型训练误差分析 从广义加法模型推导出AdaBoost训练算法&#xff0c;从而给出AdaBoost算法在理论上的解释 各种AdaBoost算法对比 标准AdaBoost算法只能用于二分类问题&#xff0c;它的改进型可以用于多分…

泽攸科技PECVD设备助力开发新型石墨烯生物传感器

近日&#xff0c;松山湖材料实验室许智团队与清华大学符汪洋合作在纳米领域头部期刊《Small》上发表了一项引人注目的研究成果&#xff0c;题为“Ultrasensitive biochemical sensing platform enabled by directly grown graphene on insulator”&#xff08;硅晶圆上直接生长…

Seatunnel MYSQL数据同步

Seatunnel MYSQL数据同步 Docker镜像 Seatunnel Docker image镜像制作-CSDN博客 数据库表 #source库 CREATE TABLE IF NOT EXISTS student(id INT UNSIGNED AUTO_INCREMENT,name VARCHAR(100) NOT NULL,age int unsigned,gender char(8) NOT NULL,PRIMARY KEY ( id ) )ENGINE…

监控易:智能告警管理,让运维无忧

监控易&#xff0c;一款卓越的运维管理工具&#xff0c;以其出色的告警中心功能帮助用户有效应对各类设备告警信息&#xff0c;保障企业IT系统的稳定运行。以下是对监控易告警中心功能的详细介绍。 一、实时告警管理&#xff0c;让设备状态尽在掌控 监控易的告警中心以列表形式…

H5移动端使用html2canvas点击按钮生成图片并下载

需求&#xff1a;点击按钮下载当前页的图片 可以用html2canvas生成canvas&#xff0c;再由canvas生成base64图片 npm install html2canvas --save import html2canvas from "html2canvas"; 遇到的问题 在保存的时候会遇到图片模糊的问题。 解决方案&#xff1a…

基于Java SSM框架实现艺诚美业美容美发管理系统项目【项目源码+论文说明】

基于java的SSM框架实现艺诚美业美容美发管理系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们…

node fs模块读取文件 readFile、readFileSync、fsPromises.readFile、createReadStream

文章目录 1.读取文件1.1 readFile1.2 readFileSync1.3 fsPromises.readFile&#xff1a;promise的写法1.4 fs.createReadStream 1.读取文件 readFile&#xff1a;异步读取文件readFileSync&#xff1a;同步读取文件fsPromises.readFile&#xff1a;promise的写法 需要注意的是…

为什么ChatGPT采用SSE协议而不是Websocket?

在探索ChatGPT的使用过程中&#xff0c;我们发现GPT采用了流式数据返回的方式。理论上&#xff0c;这种情况可以通过全双工通信协议实现持久化连接&#xff0c;或者依赖于基于EventStream的事件流。然而&#xff0c;ChatGPT选择了后者&#xff0c;也就是本文即将深入探讨的SSE&…

多账号统一登录,如何设计

多账号统一登录是一种常见的需求&#xff0c;特别是在大型应用或平台中。设计一个多账号统一登录系统需要考虑以下几个方面&#xff1a; 1. 用户标识&#xff1a;每个用户在系统中应有唯一的标识&#xff0c;可以是用户名、邮箱、手机号等。这些标识应该与账号信息关联&#x…

MC17XS6500 高边驱动芯片寄存器的介绍

本文主要是对 MC17XS6500 高边驱动芯片寄存器进行的介绍&#xff0c;MC17XS6500 寄存器分为输入寄存器和输出寄存器&#xff0c;对常用的几个输入和输出寄存器的功能和配置进行了介绍。本文中&#xff0c;世平集团基于 FlagChips FC7300 HV BMS 方案&#xff0c;对 MC17XS6500 …

Python 内置高阶函数练习(Leetcode500.键盘行)

Python 内置高阶函数练习&#xff08;Leetcode500.键盘行&#xff09; 【一】试题 &#xff08;1&#xff09;地址&#xff1a; 500. 键盘行 - 力扣&#xff08;LeetCode&#xff09; &#xff08;2&#xff09;题目 给你一个字符串数组 words &#xff0c;只返回可以使用在…

【算法】王晓东期末考题总结(一)

文章目录 分治动态规划贪心算法 分治 实现思路可参考&#xff1a;【算法】分治算法 之前写的Java版有思路。 二分搜索 #include <iostream> #include <vector>using namespace std;// 二分搜索函数 int binarySearch(const vector<int>& array, int t…

Flask笔记四之异常处理

本文首发于公众号&#xff1a;Hunter后端 原文链接&#xff1a;Flask笔记四之异常处理 在系统运行中&#xff0c;有时候需要处理报错异常。 异常的来源可能是系统在运行中的报错&#xff0c;比如错误的运算的有 1/0 这种等&#xff0c;还有的是访问了不存在接口&#xff0c;又…

docker 部署mysql

docker pull mysql:5.7.25 docker run \ --name mysql \ -e MYSQL_ROOT_PASSWORD123456 \ -p 3306:3306 \ -v /soft/mysql/conf:/etc/mysql \ -v /soft/mysql/data:/var/lib/mysql \-d \mysql:5.7.25安装好之后可以用命令行进入查看 docker exec -it mysql mysql -u root -p密…

解决ROS含动态参数的Config文件无法正确识别的错误

问题描述 功能包名为paddle_detection 在工作空间下, 通过catkin_make可以正常通过编译且执行无异常, 可以通过bloom-generate rosdebian生成依赖 但是在将其打包成deb包的过程中fakeroot debian/rules binary报错 fatal error: paddle_detection/paddle_detectionConfig.…