c语言数据结构--------拓扑排序和逆拓扑排序(Kahn算法和DFS算法实现)
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>//使用卡恩算法(Kahn)和深度优先算法(DFS)实现//拓扑排序和逆拓扑排序//拓扑排序和逆拓扑排序顶点顺序相反//图,邻接矩阵存储
#define MaxVertexNum 100 //最大顶点数typedef struct {int vex[MaxVertexNum]; //顶点表int edge[MaxVertexNum][MaxVertexNum]; //边表int vernum, arcnum; //记录当前图的顶点数量和边数
} MGraph;int vexIndex(MGraph G, int x);void visit(int i);//初始化图
MGraph InitMgraph() {MGraph graph;memset(graph.edge, 0, sizeof(graph.edge));graph.arcnum = 0;graph.vernum = 0;return graph;
}//带头节点
//链队列节点
typedef struct Linknode {int data;struct Linknode *next;
} Linknode;//链队列
typedef struct {//队头指针Linknode *front;//队尾指针Linknode *rear;
} LinkQueue;//初始化队列
void InitQueue(LinkQueue *Q) {//创建头结点Linknode *temp = (Linknode *) malloc(sizeof(Linknode));Q->front = temp;Q->rear = temp;
}//入队
void EnQueue(LinkQueue *Q, int data) {//创造节点Linknode *temp = (Linknode *) malloc(sizeof(Linknode));//赋值temp->data = data;temp->next = NULL;//连接插入节点Q->rear->next = temp;//队尾指针更换Q->rear = temp;
}//出队
bool DeQueue(LinkQueue *Q, int *e) {//队列为空if (Q->rear == Q->front) {return false;}//要出队的节点Linknode *temp = Q->front->next;*e = temp->data;//队头指针更换Q->front->next = temp->next;free(temp);//最后一个节点出队if (temp == Q->rear) {//队尾指针更换Q->rear = Q->front;}return true;
}/
//借助队列实现拓扑排序
//卡恩算法
bool TopologicalSort(MGraph G) {//初始化队列LinkQueue *linkQueue = (Linknode *) malloc(sizeof(linkQueue));InitQueue(linkQueue);//当前顶点的入度int indegree[G.vernum];//记录拓扑排序int print[G.vernum];memset(indegree, 0, sizeof(indegree));//初始化入度数组for (int i = 0; i < G.vernum; ++i) {for (int j = 0; j < G.vernum; j++) {if (G.edge[j][i] == 1) {indegree[i]++;}}}//初始化print数组memset(print, -1, sizeof(print));//度为0的顶点索引入队列for (int i = 0; i < G.vernum; i++) {if (indegree[i] == 0) {EnQueue(linkQueue, i);indegree[i] = -1;}}//记录顶点个数int count = 0;int *e = malloc(sizeof(int));while (linkQueue->rear != linkQueue->front) {DeQueue(linkQueue, e);print[count] = G.vex[*e];count++;for (int i = 0; i < G.vernum; ++i) {if (G.edge[*e][i] == 1) {indegree[i]--;}if (indegree[i] == 0) {EnQueue(linkQueue, i);indegree[i] = -1;}}}if (count < G.vernum)return false;else {for (int i = 0; i < G.vernum; i++) {printf("%d ", print[i]);}return true;}}int time;
int finalTime[100];
int visited[100];//DFS算法实现拓扑排序
//v为入度为0的顶点
void DFSTopologicalSort(MGraph G, int i) {//对i做已访问标记visited[vexIndex(G, i)] = 1;//找到i的所有邻接点for (int j = 0; j < G.vernum; j++) {if (visited[j] == 0 && G.edge[vexIndex(G, i)][j] == 1) {DFSTopologicalSort(G, G.vex[j]);}}(time)++;finalTime[vexIndex(G, i)] = time;}//使用后visited会被重新赋值,需重置
//建议用一个变量临时保存原有图
void DFSTraverseTopologicalSort(MGraph G, int i) {time = 0;for (int j = 0; j < G.vernum; j++) {visited[j] = 0;}DFSTopologicalSort(G, i);for (int j = 0; j < G.vernum; j++) {if (visited[j] == 0) {DFSTopologicalSort(G, G.vex[j]);}}for (int j = 0; j < G.vernum; j++) {printf("%d ", finalTime[j]);}
}//有向图深度优先搜索
void niDFSTopologicalSort(MGraph G, int i) {//对i做已访问标记visited[vexIndex(G, i)] = 1;//找到i的所有邻接点for (int j = 0; j < G.vernum; j++) {if (visited[j] == 0 && G.edge[vexIndex(G, i)][j] == 1) {niDFSTopologicalSort(G, G.vex[j]);}}printf("%d ", i);
}//使用后visited会被重新赋值,需重置
//建议用一个变量临时保存原有图
//连通图和非连通图的深度优先搜索(改进)
void niDFSTraverseTopologicalSort(MGraph G, int i) {for (int j = 0; j < G.vernum; j++) {visited[j] = 0;}niDFSTopologicalSort(G, i);for (int j = 0; j < G.vernum; j++) {if (visited[j] == 0) {niDFSTopologicalSort(G, G.vex[j]);}}
}int main(void) {//有向图//初始化图MGraph graph = InitMgraph();//图添加元素//顶点集添加1,2,3,4,5for (int i = 0; i < 5; i++) {graph.vex[i] = i + 1;graph.vernum++;}//边集加边<1,2>,<1,4>,<2,3>,<2,4>,<3,5>,<4,3>,<4,5>graph.edge[0][1] = 1;graph.edge[0][3] = 1;graph.edge[1][2] = 1;graph.edge[1][3] = 1;graph.edge[2][4] = 1;graph.edge[3][2] = 1;graph.edge[3][4] = 1;graph.arcnum = 7;printf("拓扑排序序列:\n");TopologicalSort(graph);printf("\n");printf("tineFinal数组:\n");DFSTraverseTopologicalSort(graph, 1);printf("\n");printf("逆拓扑排序序列:\n");niDFSTraverseTopologicalSort(graph, 5);
}//返回x在顶点表的索引
int vexIndex(MGraph G, int x) {int index = -1;for (int i = 0; i < G.vernum; i++) {if (G.vex[i] == x) {index = i;break;}}return index;
}
测试用例

相关文章:
c语言数据结构--------拓扑排序和逆拓扑排序(Kahn算法和DFS算法实现)
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h>//使用卡恩算法(Kahn)和深度优先算法(DFS)实现//拓扑排序和逆拓扑排序//拓扑排序和逆拓扑排序顶点顺序相反//图,邻接矩阵存储 #define MaxVertexNum 100 …...
谷粒微服务高级篇学习笔记整理---nginx搭建正反向代理
正向与反向代理 **正向代理:**客户端向代理服务器发请求并指定目标服务器,代理向目标转交请求并将获得的内容转给客户端。 反向代理:用户直接访问反向代理服务器就可以获得目标服务器的资源。反向代理服务器统一了访问入口。 给首页配置反向代理 修改windows的hosts文件配…...
2.pycharm保姆级安装教程
一、pycharm安装 1.官网上下载好好软,双击打开 2.下一步 3.修改路径地址 (默认也可以) 4.打勾 5.安装 不用重启电脑 二、添加解释器 1.双击软件,打开 2.projects – new project 3.指定项目名字,项目保存地址,解释器 4.右击 – …...
基于方法分类的无监督图像去雾论文
在之前的博客中,我从研究动机的角度对无监督图像去雾论文进行了分类,而现在我打算根据论文中提出的方法进行新的分类。 1. 基于对比学习的方法 2022年 论文《UCL-Dehaze: Towards Real-world Image Dehazing via Unsupervised Contrastive Learning》&a…...
【SQL】取消sql某一列的唯一值key值的方法
在插入数据到sql时,遇到了这个问题: Duplicate entry ‘XXX’ for key 起因是: 我之前设计表的时候,手动给product_title 这个列加了一个key, key 是这个字段的唯一键约束,就不能重复在这一列存入重复的数…...
数据库--SQL
SQL:Structured Query Language,结构化查询语言 SQL是用于管理关系型数据库并对其中的数据进行一系列操作(包括数据插入、查询、修改删除)的一种语言 分类:数据定义语言DDL、数据操纵语言DML、数据控制语言DCL、事务处…...
SQL语句(一)—— DDL
目录 一、SQL 基础知识 (一)SQL 通用语法 (二)SQL 分类 二、DDL —— 数据库操作 1、查询所有数据库 2、查询当前数据库 3、创建数据库 4、删除数据库 5、切换数据库 三、DDL —— 表操作 (一)查…...
硬件负载均衡:让服务像“牛顿钟”一样稳!
硬件负载均衡:让服务像“牛顿钟”一样稳! 大家好,我是 Echo_Wish,今天要聊聊提高服务可用性的一大利器——硬件负载均衡。如果你是运维领域的一员,肯定对“负载均衡”这个词耳熟能详。然而,很多朋友一提到硬件负载均衡,脑袋可能就卡住了:这是啥?跟软件负载均衡有啥区…...
Husky目标跟踪
1.0设备清单 幻影峡谷、适配器 摄像头及数据线、显卡欺骗器 外接屏幕、键盘鼠标 Husky底盘、便携显示屏、键盘鼠标 移动电源 1.1连线 插排——移动电源幻影峡谷——适配器——插排摄像头——幻影峡谷(摄像头固定在机械臂前方的底盘上)键盘鼠标显示器…...
高通camx IOVA内存不足,导致10-15x持续拍照后,点击拍照键定屏无反应,过一会相机闪退
定屏闪退问题分析思路: 定屏问题如果是相机问题,一般会出现返帧,导致预览卡死。当然还有其他情况,我们先看返帧情况,发现request和result开始都正常,到12:53:05.443038就没有返帧了,定屏了。往…...
Python----机器学习(线性回归:自求导的方法实现)
一、线性回归方程 目标: 线性回归的目标是找到最佳的系数来使模型与观察到的数据尽可能拟合。 应用: 预测:给定自变量的值,预测因变量的值。 回归分析:确定自变量对因变量的影响程度 线性回归是统计学和机器学习中最简…...
Parasoft C++Test软件单元测试_操作指南
系列文章目录 Parasoft C++Test软件静态分析:操作指南(编码规范、质量度量)、常见问题及处理 Parasoft C++Test软件单元测试:操作指南、实例讲解、常见问题及处理 Parasoft C++Test软件集成测试:操作指南、实例讲解、常见问题及处理 进阶扩展:自动生成静态分析文档、自动…...
QT之QML(简单示例)
需求一:点击按钮弹出菜单,并且自定义菜单弹出位置。 mouse.x 和 mouse.y 获取的是相对于 MouseArea(在这个例子中是 Button)左上角的局部坐标。如果你想要在鼠标点击位置显示 Menu,你需要将这个局部坐标转换为相对于应…...
【自动化运维】Python 的安装和使用
Python 的安装和使用 文章目录 Python 的安装和使用一、Linux环境安装Python1.1、设置Yum仓库1.2、安装依赖包1.3、编译Python1.3.1、解压Python压缩包1.3.2、配置Python1.3.3、编译及安装1.3.4、链接软连接 1.4、测试Python3运行1.5、设置国内pip更新源1.6、更新pip版本&#…...
Springcache+xxljob实现定时刷新缓存
目录 SpringCache详解 SpringCache概述 核心原理 接口抽象与多态 AOP动态代理 核心注解以及使用 公共属性 cacheNames KeyGenerator:key生成器 key condition:缓存的条件,对入参进行判断 注解 xxl-job详解 SpringcacheRedis实现…...
线性规划建模工具 PuLP 学习指南
PuLP 是一个用 Python 编写的线性规划建模工具,它提供了直观的 API 来定义和求解各种优化问题。以下是学习 PuLP 的全面指南: 1. 安装 PuLP pip install pulp2. 基本概念 问题类型 LpProblem: 表示优化问题LpVariable: 表示决策变量LpConstraint: 表…...
vue2拖拉拽做个模拟公式工具
1. 成图 2. 介绍 就是简单拖拉拽来做个规则运算器,具体运算规则、校验规则自己加。 3. 代码 HTML代码 <template><div class"red-cont"><div class"red-top"><divclass"red-top-left"><div class&quo…...
两点与圆(异或神通)
给出 n 个圆,保证任意两个圆都不相交且不相切。 然后给出两个点 (x1,y1),(x2,y2),保证均不在某个圆上。现在要从 (x1,y1)→(x2,y2) 画条曲线,问这条曲线最少穿过多少次圆的边界? 输入格式 第一行为一个整数 n&…...
Windows查重工具,强烈推荐大家收藏!
我大家在用电脑的时候,是不是发现用得越久,电脑里的软件和文件就越多? 今天我给大家带来的这两款重复文件查找神器,简直就是电脑里的“清洁小能手”,能帮你把那些重复的文件和文件夹找出来。 Easy DupLicate Finder 重…...
使用Python快速接入DeepSeek API的步骤指南
使用Python快速接入DeepSeek API的步骤指南 1. 前期准备 注册DeepSeek账号 访问DeepSeek官网注册账号 完成邮箱验证等认证流程 获取API密钥 登录后进入控制台 → API管理 创建新的API Key并妥善保存 安装必要库 pip install requests # 可选:处理复杂场景 pip…...
使用python完成手写数字识别
入门图像识别的第一个案例,看到好多小伙伴分享,也把自己当初的思路捋捋,写成一篇博客,作为记录和分享,也欢迎各位交流讨论。 实现思路 数据集:MNIST(包含60,000个训练样本和10,000个测试样本) 深度学习框架:Keras(基于TensorFlow) 模型架构:卷积神经网络(CNN) 实…...
OpenLayers:如何控制Overlay的层级?
我最近在使用Overlay的时候遇到了一个问题,我向地图中添加了两种不同的Overlay(下图中的蓝色标牌和粉色标牌),我希望粉色标牌可以显示在最上层,可偏偏蓝色标牌却将其遮挡住了。于是我对Overlay的层级开始起了兴趣&…...
清晰易懂的 Flutter 卸载和清理教程
以下是为 Flutter 彻底卸载与清理教程,覆盖 Windows、macOS、Linux 系统,步骤清晰无残留,确保完全删除 Flutter SDK、依赖工具及 IDE 配置。 一、通用步骤:确认 Flutter 安装方式 Flutter 通常通过以下方式安装: 手动…...
docker-compose部署以及常用命令
一:常用命令 1.docker compose restart//重启 2.docker compose down// 停止 3.docker compose ps//列出 4.sudo docker-compose up -d 启动并且在后台运行 二:yaml配置文件 version: 3.5 services:etcd:container_name: milvus-etcdimage: quay.io/coreos/etcd:…...
《Golang高性能网络编程:构建低延迟服务器应用》
在本文中,我们将深入探讨Golang高性能网络编程,帮助您构建低延迟服务器应用。我们将介绍Golang的网络编程特性、优化技巧和实际案例,让您更好地理解和应用Golang在网络编程领域的优势。 高性能网络编程简介 什么是Golang高性能网络编程 高性能…...
非对称加密技术深度解析:从数学基础到工程实践
一、密码学范式革命:从对称到非对称 1.1 对称加密的局限性 传统对称加密算法(如AES、DES)采用共享密钥机制,加解密使用相同密钥。虽然计算效率优异(AES-256加密速度可达800MB/s),但在密钥分发环…...
Ubuntu 22.04/24.04 配置apt 源
前言 在 Ubuntu 系统部署与运维中,APT 源配置是保障软件安装效率与系统稳定性的核心环节。然而,随着 Ubuntu 24.04 LTS(Noble)的发布,其 APT 源配置格式与 22.04 LTS(Jammy)存在显著差异。 …...
数据结构C语言练习(设计循环队列)
一、循环队列简介 循环队列是一种线性数据结构,基于 FIFO(先进先出)原则,将队尾连接到队首形成循环。其核心优势是能复用队列之前用过的空间,避免普通队列 “假溢出” 问题。实现时,通常申请 k1 大小的数组…...
vscode代码片段的设置与使用
在 Visual Studio Code (VS Code) 中,可以通过自定义**代码片段(Snippets)**快速插入常用代码模板。以下是详细设置步骤: 步骤 1:打开代码片段设置 按下快捷键 Ctrl Shift P(Windows/Linux)或…...
在Vue中如何高效管理组件状态
在Vue中高效管理组件状态,可以采用以下几种策略: 使用Vuex进行状态管理: 对于复杂的应用,使用Vuex是一个非常有效的状态管理方案。Vuex提供了一个集中存储管理所有组件的状态,并以响应式的方式更新视图。它包括以下几个…...
