目录

  • 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语言)相关推荐

  1. 有向无环图——AOV网及拓扑排序

    有向无环图--AOV网及拓扑排序 有向无环图 无环的有向图叫有向无环图,简称DAG图 其应用大致如下: 在工程计划和管理方面有着广泛而重要的应用 描述一项工程或系统的进行进程的有效工具 对整个工程和系 ...

  2. 有向无环图——AOV网(拓扑排序)

    有向无环图:无环的有向图,简称DAG图(Directed Acycline Graph) 有向无环图常用来描述一个工程或系统的进行过程.(通常吧计划.施工.生产.程序流程等当成是一个工程) 一个工程可 ...

  3. 带权有向无环图的最短路径(使用拓扑排序的方法)

    本文是基于带权有向无环图最短路径的实现,必需是无环的(有环不存在拓扑排序) 一.预备知识: 拓扑排序:有向图的拓扑排序是其顶点的线性排序,使得对于从顶点u 到顶点v的每个有向uv,u 在排序中都在v之 ...

  4. 有向无环图——AOE网(关键路径)

    有向无环图:无环的有向图,简称DAG图(Directed Acycline Graph) 有向无环图常用来描述一个工程或系统的进行过程.(通常吧计划.施工.生产.程序流程等当成是一个工程) 一个工程可 ...

  5. DAG - 数据结构 有向无环图

    DAG - 在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图. 其实就是指一个没有回路的有向图. 因为有向图中一个点经过两种路线到达另一个点未必形成环,因此有向 ...

  6. C语言-AOV网与拓扑排序

    邻接表: 顶点下标查找函数(LocateVex) 创建有向图的邻接表(CreateDG) 邻接表打印函数(print) 拓扑排序(TopologicalSort) AOV网与AOE网: AOV网(Ac ...

  7. 图论 —— AOV 网与拓扑排序

    [AOV网] 日常生活中,一项大的工程可以看作是由若干个子工程组成的集合,这些子工程之间必定存在一定的先后顺序,即某些子工程必须在其他的一些子工程完成后才能开始. 我们用有向图来表现子工程之间的先后关 ...

  8. 拓扑排序之AOV网及其拓扑排序思想(C语言)

    一.拓扑排序 (一)AOV⽹ AOV网(Activity On Vertex NetWork,⽤顶点表示活动的网):用DAG图(有向无环图)表示⼀个⼯程.顶点表示活动,有向边<Vi, Vj> ...

  9. 【数据结构学习记录22】——有向无环图及其应用

    有向无环图及其应用 一.有向无环图的概念 二.拓扑排序(AOV网) 1.概念 2.偏序与全序 a).偏序 b).全序 c).偏序与全序的区别 3.拓扑有序 4.拓扑排序的过程 三.关键路径(AOE网) ...

  10. java 有向无环图 树_拓扑排序-有向无环图(DAG, Directed Acyclic Graph)

    条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...

最新文章

  1. iOS 注册密码加密 添加了时间戳 遇到的问题...
  2. 短文本相似度算法研究
  3. Spring Quartz
  4. Mac下使用OpenCV
  5. CoreAPI_对象三种状态
  6. jsp java语法_javaweb-jsp语法
  7. ssm 静态资源处理器
  8. 786. 第 K 个最小的素数分数
  9. 记录对String.format(Formatter().format())方法的总结
  10. 通常也是32位的HTML5
  11. 链表的分解(C++)
  12. 华为鲁勇:华为5G专利数量全球第一 比美国所有企业还多
  13. linux通过光盘安装命令包,RHEL5通过光盘配置本地yum仓库及命令详解
  14. 在Mybatis的collection标签中获取以,分隔的id字符串
  15. python re —— 自然语言处理与正则表达式
  16. 性能优化是数据库应用的核心问题
  17. 【UEFI基础】PCD
  18. C/S架构的优点和缺点
  19. SQL Server 进程无法连接到 Subscriber “xxxxxx”
  20. AUBO E系列教育科研型机器人QA--持续更新中

热门文章

  1. 跨专业考研2022.3.8
  2. SQL server基本的代码操作
  3. 计算机组成原理个人小结
  4. 使用Golang搭建gRPC服务提供给.NetCore调用
  5. 上海数据交易中心CEO申翔宇:数据互联,引领智慧未来
  6. 服务器03系统 打印机,win 2003下如何配置打印服务器及打印机
  7. 随机生成10个不重复的0-100的数字
  8. Oracle的100+个常用函数
  9. 整车公告流程--汽车公告
  10. scanf的返回值及其应用(多组输入)