拓扑排序算法的实现

本文介绍了一种基于邻接表的图数据结构实现拓扑排序的算法,并通过C语言进行了详细解析。文中提供了完整的源代码及运行实例,帮助读者理解拓扑排序的基本原理及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


![在这里插入图片描述](https://img-blog.csdnimg.cn/313a3ba16dfd476eb8d0da7dd21cfb27.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNTM0Mzk0NzQ=,size_20,color_FFFFFF,t_70,g_se,x_16)
[视频链接](https://www.bilibili.com/video/BV1Wp4y1X79x?spm_id_from=333.999.0.0)
[ppt链接](https://zhuanlan.zhihu.com/p/391650129)

```c
//拓扑排序算法
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//定义边表结构
struct Arcnode {
	int adjvex;
	Arcnode* next;
};
//定义顶点表结构
struct Vertexnode {
	int in;
	char vertex;
	Arcnode* first;
};
//定义图结构
struct Graph
{
	Vertexnode adjlist[100];
	int vernum;
	int arcnum;
};

const int MAX_VERTEX = 10;
//Vertexnode adjlist[MAX_VERTEX];
//创建图
void Creategraph(Graph &g,char a[],int b[], int n, int e)
{
	 g.vernum = n;
	 g.arcnum = e;
	for (int i = 0; i < g.vernum; i++)
	{
		g.adjlist[i].vertex = a[i];
		g.adjlist[i].first = NULL;
		g.adjlist[i].in = b[i];
	}
	for (int i = 0; i < g.arcnum; i++)
	{
		int vi, vj,in;
		int num = 0;
		printf("请输入边的起点和终点序号");
		scanf_s("%d,%d", &vi, &vj);

		Arcnode* s = (Arcnode*)malloc(sizeof(Arcnode));
		s->adjvex = vj;
		s->next = NULL;
			s->next = g.adjlist[vi].first;
			g.adjlist[vi].first = s;

	}
}

void Topology(Graph g)
{
	int stack[100];
	int count = 0, top = 0;
	//初始化栈,扫描入度为零的顶点压入栈中,栈记录的是元素的编号而不是内容
	for (int i = 0; i < g.vernum; i++)
	{
		if (g.adjlist[i].in == 0)
		{
			stack[top] = i;
			top++;
		}
	}
	//当栈中还有元素执行循环体
	while (top > 0)
	{//取栈顶元素
		int curr = stack[--top];
		//输出
		printf("%c ", g.adjlist[curr].vertex);
		count++;//输出累加器
		Arcnode* p = g.adjlist[curr].first;//指向栈顶元素的第一个邻接点,若存在不为空执行循环体,
		while (p != NULL)
		{
			g.adjlist[p->adjvex].in--;//邻接点入度减一
			if (g.adjlist[p->adjvex].in == 0)//若入读减一后为零则邻接点入栈
			{
				stack[top] = p->adjvex;
				top++;
			}
			p = p->next;//指向下一个邻接点
		}
	}
	if (count < g.vernum)//若输出顶点数小于实际顶点数则有回路
		printf("有回路");
}


//深度递归遍历
//int vist[MAX_VERTEX] = { 0 };
//void DFStraverse(Graph g,int v) {
//	vist[v] = 1;
//	printf("%c", g.adjlist[v].vertex);
//	Arcnode* p = g.adjlist[v].first;
//	while (p != NULL)
//	{
//		if (vist[p->adjvex] == 0)
//		{
//			DFStraverse(g,p->adjvex);
//			p = p->next;
//		}
//	}
//}

int main()
{
	Graph g;
	char verlist[] = "ABCDEF";
	int in[] = { 3,0,1,3,0,2 };
	Creategraph(g,verlist,in,6,9);
	Topology(g);
	//DFStraverse(g,0);

}

![在这里插入图片描述](https://img-blog.csdnimg.cn/32e0d6f92b4a4b099872bc2c3d5aedb2.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNTM0Mzk0NzQ=,size_20,color_FFFFFF,t_70,g_se,x_16)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值