细说拓扑排序

本文详细介绍了拓扑排序的概念,它适用于有向无环图(DAG),并提供了拓扑排序的基本算法实现。通过宽度优先遍历,从入度为0的节点开始,逐步构建拓扑序列。拓扑排序的结果不唯一,但能确保图中任意节点的前驱在序列中位于其前面。文章还提供了一个C++模板代码来展示具体操作过程。

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

首先,拓扑排序是将一个图中所有节点排成一个线性序列,使得任意一对节点a和b,在图中a在b的上位,那么在序列中a就在b的前面,这样的序列被称为拓扑序列,因此,拓扑排序只能用于有向无环图,无向图中因为存在环路所以没有拓扑序列。

实现方法:

拓扑序列用一个队列数组储存。

拓扑排序需要用到入度的概念,一个节点的入度就是有其他点指向该点的边的数量,与之相对的还有一个点的出度是指由该点出发的指向其他点的的边的数量。

了解了入度的概念后,我们就知道任意一个入度为0的节点都可以作为拓扑序列的起点。

先将所有入度为0的点入队,然后枚举这些点的出边,再删掉该点,而出边对应的另一个点的入度就减1,在对新得到的入度为0的点进行同样操作,直到所用的点都处理过,最终得到储存了拓扑序列的队列数组。具体的遍历方式用的是图的宽度优先遍历。

主要模板:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=1000010;
int h[N],e[N],ne[N],idx,q[N],d[N];//其中q是队列数组,d数组表示每个点的入度

void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
//基本的储存函数

bool topsort()
{
	int hh=0,tt=-1;
	for(int i=1;i<=n;i++)
		if(!d[i])
			q[++tt]=i;//入度为0,队尾存入
			
	while(hh<=tt)
	{
		int t=q[hh++];//将对头取出存入t另作处理并删除
		for(int i=h[t];i!=-1;i=ne[i])
		{
			int j=e[i];
			d[j]--;
			if(!d[j]) q[++tt]=j;
		}
	}

	return tt==n-1;//当tt=n-1,说明队尾已添加过n次,已将n个数全部遍历,也就代表图存在拓扑序列
}

最后输出队列即可得到图的一个拓扑序列,一个图的拓扑序列不唯一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值