南京工业大学2023数据结构复习题简析【编程题5】
题目:拓扑排序算法的基本思想
一、基本概念
拓扑排序是一个非常容易理解的概念。我们要回忆一下入度这个概念。
我们想象这样一个图,里面只有两个结点A和B,且只有一条从A指向B的边。那么此时,我们称A的入度为0,B的入度为1。
也就是说,某个结点被几个结点指向,那么它的入度就是几。
所谓拓扑排序,就是每次出队的结点入度都为0。这样一直循环下去,就能将一个图中的结点进行排序。
二、代码实现
(1)初步框架
1.头文件:
#include <stdio.h>
#include <stdlib.h>
2.规定一下点的最大个数(这里以9个点为例):
#define MaxVertex 9
3.定义结点的结构体:
由于用的是邻接表,所以普通的结点和头结点要分开定义。
typedef struct LNode{int nextVertex;struct LNode *next;
}*Node;
4.定义头结点的结构体:
这里存放的是入度。
struct HeadNode{int inDegree;struct LNode *next;
};
5.定义邻接表结构体:
typedef struct Adj{int vertexCount;int edgeCount;struct HeadNode vertex[MaxVertex];
}*Graph;
(2) 邻接表的基本操作:
1.创建一个邻接表:
Graph createGraph(){Graph graph = (Graph)malloc(sizeof(struct Adj));graph -> vertexCount = graph -> edgeCount = 0;return graph;
}
2.插入点:
void addVertex(Graph graph){graph -> vertex[graph -> vertexCount].inDegree = 0;graph -> vertex[graph -> vertexCount].next = NULL;graph -> vertexCount++;
}
3.插入边:
void addEdge(Graph graph, int a, int b){Node node = graph -> vertex[a].next;//newNode为新建的结点,存放b,待插入Node newNode = (Node)malloc(sizeof(struct LNode));newNode -> nextVertex = b;newNode -> next = NULL;//如果node为空,也就是说这个结点之前没有指向任何其他结点,那么直接插入即可if(node == NULL) graph -> vertex[a].next = newNode; else{//否则一直向后找do{if(node -> nextVertex == b) return ; //如果发现a已经指向b了,直接结束if(node -> next) node = node -> next; //如果node还有下一个元素,就继续遍历else break; //已经找到最后一个了,跳出循环}while(1);node -> next = newNode; //在最后一个结点后插入即可}graph -> vertex[b].inDegree++; //b的入度加1graph -> edgeCount++; //总边数加1
}
(3)拓扑排序函数:
首先我们定义一个队列,将表中所有入度为0的结点入队。然后进入while循环,从队列的第一个元素开始打印出队,并更新删除该结点后剩余结点的入度。如果有新入度为0的结点,就将其入队。这样反复操作下去,我们就完成了排序。
void topologicalSort(Graph graph){int queue[MaxVertex];int front = 0, rear = 0;for(int i = 0; i < MaxVertex; i++){if(graph -> vertex[i].inDegree == 0){queue[rear++] = i;}}while(front != rear){int v = queue[front++];if(graph -> vertex[v].next == NULL && front == rear){printf("%d", v);break;}printf("%d -> ", v);Node node = graph -> vertex[v].next;while(node){int w = node -> nextVertex;if(--graph -> vertex[w].inDegree == 0){queue[rear++] = node -> nextVertex;}node = node -> next;}}
}
三、测试效果
int main(){Graph graph = createGraph();for(int i = 0; i < 4; i++){addVertex(graph);}addEdge(graph, 3, 0);addEdge(graph, 3, 2);addEdge(graph, 0, 1);addEdge(graph, 0, 2);topologicalSort(graph);return 0;
}
运行结果:
四、完整代码
#include <stdio.h>
#include <stdlib.h>#define MaxVertex 4typedef struct LNode{int nextVertex;struct LNode *next;
}*Node;struct HeadNode{int inDegree;struct LNode *next;
};typedef struct Adj{int vertexCount;int edgeCount;struct HeadNode vertex[MaxVertex];
}*Graph;Graph createGraph(){Graph graph = (Graph)malloc(sizeof(struct Adj));graph -> vertexCount = graph -> edgeCount = 0;return graph;
}void addVertex(Graph graph){graph -> vertex[graph -> vertexCount].inDegree = 0;graph -> vertex[graph -> vertexCount].next = NULL;graph -> vertexCount++;
}void addEdge(Graph graph, int a, int b){Node node = graph -> vertex[a].next;//newNode为新建的结点,存放b,待插入Node newNode = (Node)malloc(sizeof(struct LNode));newNode -> nextVertex = b;newNode -> next = NULL;//如果node为空,也就是说这个结点之前没有指向任何其他结点,那么直接插入即可if(node == NULL) graph -> vertex[a].next = newNode; else{//否则一直向后找do{if(node -> nextVertex == b) return ; //如果发现a已经指向b了,直接结束if(node -> next) node = node -> next; //如果node还有下一个元素,就继续遍历else break; //已经找到最后一个了,跳出循环}while(1);node -> next = newNode; //在最后一个结点后插入即可}graph -> vertex[b].inDegree++; //b的入度加1graph -> edgeCount++; //总边数加1
}void topologicalSort(Graph graph){int queue[MaxVertex];int front = 0, rear = 0;for(int i = 0; i < MaxVertex; i++){if(graph -> vertex[i].inDegree == 0){queue[rear++] = i;}}while(front != rear){int v = queue[front++];printf("%d -> ", v);Node node = graph -> vertex[v].next;while(node){int w = graph -> vertex[node -> nextVertex].inDegree;if(--w == 0){queue[rear++] = node -> nextVertex;}node = node -> next;}}
}int main(){Graph graph = createGraph();for(int i = 0; i < 4; i++){addVertex(graph);}addEdge(graph, 3, 0);addEdge(graph, 3, 2);addEdge(graph, 0, 1);addEdge(graph, 0, 2);topologicalSort(graph);return 0;
}
南京工业大学2023数据结构复习题简析【编程题5】相关推荐
- 南京工业大学2023数据结构复习题简析【编程题2】
题目:循环链表中结点的基本操作 考虑到没有说明是单循环链表还是双循环链表,秉持准备充分的原则,我们采用双向循环链表来完成这个问题. 一.初步框架 1.头文件: #include <stdio.h ...
- 南京工业大学2023数据结构复习题简析【编程题3】
题目:图的邻接矩阵表示法 注意:本文中所面向的图是有向图 一.初步框架 1.头文件: #include <stdio.h> #include <stdlib.h> 2.定义邻接 ...
- 南京工业大学2023数据结构复习题简析【编程题4】
题目:Floyd算法求取图中每一对顶点之间的最短距离 一.快速回忆 Q1:Floyd算法的作用是什么? 答:那必然是求取图中每一对顶点之间的最短距离(见题目). Q2:Floyd算法需要基于什么来实现 ...
- “四非”高校南京工业大学,17天内三连击Nature、Science!实为深藏不露
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者 | 维克多 <Nature>和<Science>杂志创刊已有百余年,作为 ...
- 南工计算机调剂,南京工业大学2021年硕士研究生调剂公告
一.申请条件 1.申请调剂考生需符合<教育部关于印发<2021年全国硕士研究生招生工作管理规定>的通知>(教学函( 2020 )8号)要求. 2.非全日制硕士研究生需以定向就业 ...
- 【调剂】南京信息工程大学2023年中外合作计算机,电子信息都招!
公众号[计算机与软件考研]每天都会发布最新的计算机考研调剂信息! 点击公众号界面左下角的调剂信息或者公众号回复"调剂"是计算机/软件等专业的所有调剂信息集合,会一直更新的. 南京信 ...
- 南工大计算机录取分数线,南京工业大学2016年录取分数线
南京工业大学2016年录取分数线 省份 批次 科类 最高分 最低分 辅助排序分 河北 艺术提前批 艺术 712 550 山西 艺术提前批 艺术 687 589 361 内蒙 ...
- 河南工业大学c语言考试题库,c语言题库(编程)河南工业大学 河工大 c语言期末考试题库...
c语言题库(编程)河南工业大学 河工大 c语言期末考试题库 (27页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 C语言题库编程河南工业 ...
- 南京工业大学python考试期末题库_大学慕课用Python玩转数据期末考试查题公众号答案...
大学慕课用Python玩转数据期末考试查题公众号答案 更多相关问题 雪松的树形为 (5.0分) - Do you think I can borrow your bike for a few hour ...
最新文章
- 虚拟服务器nodejs项目部署打包,nodejs+express搭建服务器及vue项目部署打包
- Android源码学习之工厂方法模式应用
- Sharepoint学习笔记—Site Definition系列-- 3、创建ListDefinition
- Centos7下安装Python3.5
- 串的模式匹配(BF算法)
- 新来的前端小姐姐问:Vue路由history模式刷新页面出现404问题
- Intel Core Enhanced Core架构/微架构/流水线 (14) - 存储器/内存读写 Memory Load/Store
- XX基金 机器学习平台使用情况访谈总结
- nest.js实战之集成Linkedin登录
- oracle常用查询语句
- C++ 中cin的输入原理及字符串(string、char[])输入问题
- C语言求阶乘与阶乘和
- 透视相机(PerspectiveCamera)
- 使用DreamweaverMX2004的搜索替换功能提高工作效率。
- 幼麟棋牌登录socket服务器分析
- 语言表达的6c原则是指什么,第二讲 BEC写作的语言、语法、组织和文体
- 几十年前的老旧照片如何修复?还不知道旧照片怎么恢复清晰吗?
- 实验02-微信公众号编辑模式应用
- 职场新境之“甩手组”
- Java 创建并用应用幻灯片母版
热门文章
- Win10更改注册表win defend键值提示无法更改所有者
- android时间接收器,android – 在飞机模式关闭/打开后,广播接收器在onReceive()中接收的时间太长...
- Fiddler 工作原理和使用
- 读 在浮躁的年代里做学问..
- 烧水壶java代码_JAVA代码—算法基础:水壶分水的问题
- mysql tinyint
- springboot毕设项目多层级架构的工程项目安全监管系统的设计与实现tx75u(java+VUE+Mybatis+Maven+Mysql)
- uC-OS2 V2.93 STM32L476 移植:系统移植篇
- Java二分法查找最大值
- 机器人创客加盟的几点建议