【数据结构】有向无环图(AOV-网)的拓扑排序(C语言)
目录
- 1. 拓扑序列
- 2. 拓扑排序的实现(以邻接表为例)
- 2.1 基本思想
- 2.2 完整实现代码及运行结果
1. 拓扑序列
有向无环图是指一个无环的有向图。有向无环图可用来描述工程或系统的进行过程,如一个工程的施工图、学生课程间的制约关系图等。
用顶点表示活动,用弧表示活动间优先关系的有向无环图,称为顶点表示活动的网,简称AOV-网。
拓扑序列:在有向图G =(V,{E})中,V中顶点的线性序列(v1,v2,v3,…,vn)称为拓扑序列。如果此序列满足条件:对序列中任意两个顶点vi,vj,在G中有一条从vi到vj的路径,则在序列中vi必排在vj之前。
AOV-网的特性:
① 若 vi 为 vj 的先行活动,vj 为 vk 的先行活动,则 vi 必为 vk 的先行活动,即先行关系具有可传递性。
② AOV-网的拓扑序列不唯一。如上图有向无环图的另一个拓扑序列为:C1,C2,C3,C8,C4,C5,C9,C7,C6。
拓扑排序(Topological Sort)的基本思想:
① 从有向图中选择一个无前驱的结点输出;
② 将此结点和以它为起点的边删除;
③ 重复①、②直到不存在无前驱的结点;
④ 若此时输出的结点数小于有向图中的顶点数,则说明有向图中存在回路,否则输出的顶点的顺序即为一个拓扑序列。
示例:
2. 拓扑排序的实现(以邻接表为例)
2.1 基本思想
入度为0的顶点即没有前驱的顶点,对于邻接表结构可以附设一个存放各顶点入度的数组indegree[],于是有:
① 找G中无前驱的结点——查找indegree[i]为0的顶点i;
② 删除以 i 为起点的所有弧——对链在顶点 i 后面的所有邻接顶点 k,将对应的indegree[k]减1;
(注:若存储结构为邻接矩阵,则
① 找G中无前驱的结点——在邻接矩阵中找到值全为0的列;
② 删除以 i 为起点的所有弧——将矩阵中 i 对应的行全部置为0;)
为避免重复检测入度为0的顶点,可以设置一个辅助栈,若某一顶点的入度减为0,则将它入栈,每当输出某一顶点时,便将它从栈中删除,即出栈。
2.2 完整实现代码及运行结果
# include<stdio.h>
# include<malloc.h>
# define MAX_VERTEX_NUM 20
# define TRUE 1
# define FALSE 0/*图的邻接表表示法*/
typedef char VertexData;
//弧结点结构
typedef struct ArcNode {int adjvex; //该弧指向顶点的位置struct ArcNode* nextarc; //指向下一条弧的指针
}ArcNode;
//表头结点结构
typedef struct VertexNode {VertexData data; //顶点数据ArcNode* firstarc; //指向该顶点的第一条弧的指针
}VertexNode;
//邻接表结构
typedef struct {VertexNode vertex[MAX_VERTEX_NUM];int vexnum, arcnum; //图的顶点数和弧数
}AdjList;/*求顶点位置*/
int LocateVertex(AdjList* G, VertexData v) {int k;for (k = 0; k < G->vexnum; k++) {if (G->vertex[k].data == v)break;}return k;
}/*创建有向图的邻接表*/
int CreateAdjList(AdjList* G) {int i, j, k;VertexData v1, v2;ArcNode* p;printf("输入图的顶点数和弧数:"); //输入图的顶点数和弧数scanf("%d%d", &G->vexnum, &G->arcnum);printf("输入图的顶点:");for (i = 0; i < G->vexnum; i++) { //输入图的顶点,初始化顶点结点scanf(" %c", &(G->vertex[i].data));G->vertex[i].firstarc = NULL;}for (k = 0; k < G->arcnum; k++) {printf("输入第%d条弧的两个顶点:", k + 1);scanf(" %c %c", &v1, &v2); //输入一条弧的两个顶点i = LocateVertex(G, v1);j = LocateVertex(G, v2);p = (ArcNode*)malloc(sizeof(ArcNode)); //申请新弧结点p->adjvex = j;p->nextarc = G->vertex[i].firstarc;G->vertex[i].firstarc = p;}
}/*顺序栈的存储结构,辅助栈*/
typedef struct {int elem[MAX_VERTEX_NUM]; //用于存放栈中元素的一维数组int top; //存放栈顶元素的下标,top为-1表示空栈
}SeqStack;/*初始化顺序栈*/
void InitStack(SeqStack* S) {S->top = -1;
}/*判空*/
int IsEmpty(SeqStack* S) {if (S->top == -1) //栈为空return TRUE;elsereturn FALSE;
}/*顺序栈进栈*/
int Push(SeqStack* S, int x) {if (S->top == MAX_VERTEX_NUM - 1) //栈已满return FALSE;S->top++;S->elem[S->top] = x; //x进栈return TRUE;
}/*顺序栈出栈*/
int Pop(SeqStack* S) {if (S->top == -1) //栈为空return FALSE;S->top--;return TRUE;
}int indegree[MAX_VERTEX_NUM]; //存放各顶点入度/*求各顶点入度算法*/
void FindID(AdjList G) {int i;ArcNode* p;for (i = 0; i < G.vexnum; i++)indegree[i] = 0;for (i = 0; i < G.vexnum; i++) {p = G.vertex[i].firstarc;while (p != NULL) {indegree[p->adjvex]++;p = p->nextarc;}}
}/*拓扑排序算法*/
int TopoSort(AdjList G) {int i, count = 0, k;SeqStack S;ArcNode* p;FindID(G); //求各顶点入度InitStack(&S); //初始化辅助栈for (i = 0; i < G.vexnum; i++) {if (indegree[i] == 0)Push(&S, i); //将入度为0的顶点入栈}while (!IsEmpty(&S)) {i = S.elem[S.top];Pop(&S);printf("%c ", G.vertex[i]);count++;p = G.vertex[i].firstarc;while (p != NULL) {k = p->adjvex;indegree[k]--; //i号顶点的每个邻接点的入度减1if (indegree[k] == 0)Push(&S, k); //若入度减为0则入栈p = p->nextarc;}}if (count < G.vexnum) {printf("该图存在回路!\n");return FALSE;}elsereturn TRUE;
}int main() {AdjList G;CreateAdjList(&G);printf("\n拓扑排序:");TopoSort(G);return 0;
}
运行结果
参考:耿国华《数据结构——用C语言描述(第二版)》
更多数据结构内容关注我的《数据结构》专栏:https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482
【数据结构】有向无环图(AOV-网)的拓扑排序(C语言)相关推荐
- 有向无环图——AOV网及拓扑排序
有向无环图--AOV网及拓扑排序 有向无环图 无环的有向图叫有向无环图,简称DAG图 其应用大致如下: 在工程计划和管理方面有着广泛而重要的应用 描述一项工程或系统的进行进程的有效工具 对整个工程和系 ...
- 有向无环图——AOV网(拓扑排序)
有向无环图:无环的有向图,简称DAG图(Directed Acycline Graph) 有向无环图常用来描述一个工程或系统的进行过程.(通常吧计划.施工.生产.程序流程等当成是一个工程) 一个工程可 ...
- 带权有向无环图的最短路径(使用拓扑排序的方法)
本文是基于带权有向无环图最短路径的实现,必需是无环的(有环不存在拓扑排序) 一.预备知识: 拓扑排序:有向图的拓扑排序是其顶点的线性排序,使得对于从顶点u 到顶点v的每个有向uv,u 在排序中都在v之 ...
- 有向无环图——AOE网(关键路径)
有向无环图:无环的有向图,简称DAG图(Directed Acycline Graph) 有向无环图常用来描述一个工程或系统的进行过程.(通常吧计划.施工.生产.程序流程等当成是一个工程) 一个工程可 ...
- DAG - 数据结构 有向无环图
DAG - 在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图. 其实就是指一个没有回路的有向图. 因为有向图中一个点经过两种路线到达另一个点未必形成环,因此有向 ...
- C语言-AOV网与拓扑排序
邻接表: 顶点下标查找函数(LocateVex) 创建有向图的邻接表(CreateDG) 邻接表打印函数(print) 拓扑排序(TopologicalSort) AOV网与AOE网: AOV网(Ac ...
- 图论 —— AOV 网与拓扑排序
[AOV网] 日常生活中,一项大的工程可以看作是由若干个子工程组成的集合,这些子工程之间必定存在一定的先后顺序,即某些子工程必须在其他的一些子工程完成后才能开始. 我们用有向图来表现子工程之间的先后关 ...
- 拓扑排序之AOV网及其拓扑排序思想(C语言)
一.拓扑排序 (一)AOV⽹ AOV网(Activity On Vertex NetWork,⽤顶点表示活动的网):用DAG图(有向无环图)表示⼀个⼯程.顶点表示活动,有向边<Vi, Vj> ...
- 【数据结构学习记录22】——有向无环图及其应用
有向无环图及其应用 一.有向无环图的概念 二.拓扑排序(AOV网) 1.概念 2.偏序与全序 a).偏序 b).全序 c).偏序与全序的区别 3.拓扑有序 4.拓扑排序的过程 三.关键路径(AOE网) ...
- java 有向无环图 树_拓扑排序-有向无环图(DAG, Directed Acyclic Graph)
条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...
最新文章
- iOS 注册密码加密 添加了时间戳 遇到的问题...
- 短文本相似度算法研究
- Spring Quartz
- Mac下使用OpenCV
- CoreAPI_对象三种状态
- jsp java语法_javaweb-jsp语法
- ssm 静态资源处理器
- 786. 第 K 个最小的素数分数
- 记录对String.format(Formatter().format())方法的总结
- 通常也是32位的HTML5
- 链表的分解(C++)
- 华为鲁勇:华为5G专利数量全球第一 比美国所有企业还多
- linux通过光盘安装命令包,RHEL5通过光盘配置本地yum仓库及命令详解
- 在Mybatis的collection标签中获取以,分隔的id字符串
- python re —— 自然语言处理与正则表达式
- 性能优化是数据库应用的核心问题
- 【UEFI基础】PCD
- C/S架构的优点和缺点
- SQL Server 进程无法连接到 Subscriber “xxxxxx”
- AUBO E系列教育科研型机器人QA--持续更新中