数据结构-拓扑排序

这篇具有很好参考价值的文章主要介绍了数据结构-拓扑排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

情景引入 

一个无环的有向图称作有向无环图(Directed Acycline Graph),简称DAG图。

DAG图是描述含有公共子式的表达式的有效工具。

在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,称这种有向图为顶

点表示活动的网,简称AOV网。

AOV网中不能出现回路,而判断一个AOV网是否有回路,可以通过“拓扑排序”来判断。

算法思想

1.从一个AOV网中选择一个没有前驱的顶点输出它。

2.从AOV网中删除该顶点,并且删去所有以该顶点为尾的弧。

3.重复上述两步,直到顶点全部被输出,或AOV网中不存在没有前驱的顶点位置。

显然,若最后顶点全部被输出,代表AOV网中没有回路。

若顶点没有被全部输出,即AOV网中还存在有前驱的顶点。

那么,在程序层次我们该怎么实现呢?

因为在拓扑排序中需要查找所有以某个顶点为尾的弧,需要找到该顶点的所有出边,为此,图应该

采用邻接表存储。

同时,因为还要判断某个顶点有没有入度,即找到没有前驱的顶点,我们还需要一个辅助数组

degree数组用来确定某个顶点的入度。

另外,为了防止重复检测入度为0的顶点,可以设置一个栈来暂存所有入度为0的顶点。

代码部分

#include<stdio.h>
#include<malloc.h>
#define MAX 100

typedef struct ArcNode{
	int adjvex;
	int weight;
	struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode{
	char vertex;
	ArcNode *firstarc;
}VNode;
typedef VNode AdjList[MAX];
typedef struct ALGraph{
	AdjList adjlist;
	int vexnum,arcnum;
}ALGraph;

int LocateVertex(ALGraph *G,char v)
{
	int k;
	for(k=0;k<G->vexnum;k++)
		if(G->adjlist[k].vertex == v)
			return k;
	return -1;	
}

void CreateALGraph(ALGraph *G)
{
	int i,l1,l2,weight;
	char v1,v2;
	printf("请输入顶点数和边数:\n");
	scanf("%d%d",&G->vexnum,&G->arcnum);
	getchar();
	printf("请输入{%d}个顶点:\n",G->vexnum);
	for(i=0;i<G->vexnum;i++){
		scanf("%c",&G->adjlist[i].vertex);
		G->adjlist[i].firstarc = NULL;
	}
	getchar();
	printf("请输入{%d}条边,格式如(v1 v2 权值)\n",G->arcnum);
	for(i=0;i<G->arcnum;i++){
		scanf("%c %c %d",&v1,&v2,&weight);
		getchar();
		l1 = LocateVertex(G,v1);
		l2 = LocateVertex(G,v2);
		if(l1 == -1 || l2 == -1){
			printf("失败.\n");
			i = i - 1;
			continue;
		}
		else{
			ArcNode *tmp = (ArcNode*)malloc(sizeof(ArcNode));
			tmp->adjvex = l2;
			tmp->weight = weight;
			tmp->nextarc = G->adjlist[l1].firstarc;
			G->adjlist[l1].firstarc = tmp;
			printf("成功.\n");
		}
	}
}

void FindInDegree(ALGraph *G,int *indegree)		//求入度函数 
{
	int i;
	ArcNode *p;
	for(i=0;i<G->vexnum;i++)
		indegree[i] = 0;		//初始化 indegree数组全部置为0 
	for(i=0;i<G->vexnum;i++){
		p = G->adjlist[i].firstarc;
		while(p){		//对p节点进行遍历 
			indegree[p->adjvex]++;		//对应索引入度加一 
			p = p->nextarc;
		}
	}
}

void TopologicalSort(ALGraph *G,int n)
{
	int indegree[n];
	int i,j,count;
	int top;
	ArcNode *p;
	FindInDegree(G,indegree);	//求该图的所有顶点入度
	top = 0;
	for(i=0;i<G->vexnum;i++){		//遍历图中顶点入度为0的顶点 
		if(indegree[i] == 0){		//如果顶点入度为0,那么入栈 
			indegree[i] = top;		//令该顶点值为top指针的值 
			top = i + 1;			//top指针加一 
		}
	} 
	count = 0;
	while(top!=0){
		i = top - 1;		//top指针减一 
		top = indegree[i];
		printf("移除顶点:{%c}\n",G->adjlist[i].vertex);
		count++;
		for(p=G->adjlist[i].firstarc;p;p=p->nextarc){		//模拟移除以该顶点为弧尾的边 
			j = p->adjvex;			//这里的移除边,并不是真的删除这条边,而是数量减一 
			if(--indegree[j] == 0){		//--表示该顶点入度减一后是否为0 
				indegree[j] = top;		 //如果入度为0了,需要入栈 
				top = j + 1;		//top指针加一 
			}
		}
	}
	if(count < n){
		printf("该图有回路.\n");
	} 
	else{
		printf("该图没有回路.\n");
	}
}

int main()
{
	ALGraph G;
	CreateALGraph(&G);
	TopologicalSort(&G,G.vexnum);
	return 0;
} 

验证部分

现在我们考虑下面这个例子:

数据结构-拓扑排序,数据结构,算法

很显然该图是无环的。

运行结果:

数据结构-拓扑排序,数据结构,算法

我们再看这个例子:

数据结构-拓扑排序,数据结构,算法

很显然这个图是有环的。

运行结果:

数据结构-拓扑排序,数据结构,算法

符合我们的要求。文章来源地址https://www.toymoban.com/news/detail-721339.html

到了这里,关于数据结构-拓扑排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 教学计划编制问题(数据结构 有向图 拓扑排序)

     本文对以下教学计划编制问题的解决作出实现,主要使用c语言(带一点cpp),开发环境为codeblocks 17.12,希望对各位读者有所帮助。(源码和数据文件可在主页获取,同时还有使用视频文件压缩包,数据文件需要和exe在同一目录下,结合某读者的意见同时放到github了 ) 地址如下

    2024年02月09日
    浏览(56)
  • 【数据结构】图的应用:最小生成树;最短路径;有向无环图描述表达式;拓扑排序;逆拓扑排序;关键路径

    目录 1、最小生成树 1.1 概念  1.2 普利姆算法(Prim) 1.3 克鲁斯卡尔算法(Kruskal)  2、最短路径 2.1 迪杰斯特拉算法(Dijkstra) 2.2 弗洛伊德算法(Floyd)  2.3 BFS算法,Dijkstra算法,Floyd算法的对比 3、有向无环图描述表达式 3.1 有向无环图定义及特点 3.2 描述表达式 4、拓扑排序

    2024年02月07日
    浏览(50)
  • 【数据结构——有向图】有环无环判定、拓扑排序(DFS、BFS)

    有向图(Directed Graph),也被称为有向图形或方向图,是一种图的类型。在有向图中,图中的边具有方向,从一个顶点指向另一个顶点。 在有向图中,每个顶点表示一个实体,而有向边则表示实体之间的关系或连接。这种有方向性的边表明了连接的起点和终点之间的单向关系

    2024年02月09日
    浏览(50)
  • 数据结构拓扑排序以及关键路径(出度邻接表)C语言 完整代码

    现实生活中一项工程通常会拆分成多个部分来进行,这些部分有些相互之间有发生的前提关系,还有些可以同时发生且不会互相打扰,但是合理且充分的利用时间来完成项目是一个问题。在项目完成的过程中,那些项目的完成时间被压缩可以压缩工程的总时间,以便于提高整

    2024年02月04日
    浏览(49)
  • 【数据结构】拓扑网络(AOE算法举例+源码)

    博主介绍:✌专研于前后端领域优质创作者、本质互联网精神开源贡献答疑解惑、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦! 🍅文末获取源码联系🍅 👇🏻 精彩专栏

    2024年02月22日
    浏览(48)
  • 数据结构——排序算法——归并排序

    在第二个列表向第一个列表逐个插入的过程中,由于第二个列表已经有序,所以后续插入的元素一定不会在前面插入的元素之前。在逐个插入的过程中,每次插入时,只需要从上次插入的位置开始,继续向后寻找插入位置即可。这样一来,我们最多只需要将两个有序数组遍历

    2024年02月09日
    浏览(47)
  • 【排序算法】数据结构排序详解

    前言: 今天我们将讲解我们数据结构初阶的最后一部分知识的学习,也是最为“炸裂”的知识---------排序算法的讲解!!!! 排序 :所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性 :假定在待排序的记录序列中,

    2023年04月08日
    浏览(50)
  • 数据结构和算法笔记4:排序算法-归并排序

    归并排序算法完全遵循分治模式。直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决:使用归并排序递归地排序两个子序列。 合并:合并两个已排序的子序列以产生已排序的答案。 我们直接来看例子理解算法的过程,下面是要排序

    2024年01月21日
    浏览(64)
  • 【数据结构与算法】十大经典排序算法-希尔排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对

    2024年02月12日
    浏览(80)
  • 【数据结构与算法】十大经典排序算法-快速排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 快速排序(Quick Sort)是一种高效的排序算法,是对冒泡排序的优化。它采用分治法(Divide and Conquer)的思想,将待排序序列

    2024年02月13日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包