图论算法:拓扑排序

前面介绍了图论算法基础,下面在图论基础上介绍图论算法中的拓扑排序。

简介

拓扑排序是对有向无环图DAG的顶点的一种排序算法,如果在图中存在一条路径从顶点v到顶点w,则在排序中,顶点v在w前面。拓扑排序对带环图无意义,因为无法确定环中顶点的先后顺序。拓扑排序在一些场景下很有用,比如学校排课时,必须保证先修完课程A然后才能修课程B,此时就可以用拓扑排序。

算法实现

顶点v的入度(indegree):指向顶点v的边的条数。
在这里插入图片描述
上图中v1的入度为2,v2的入度为0,v3的入度为1,……

1、简单实现

拓扑排序的简单实现:先找出图中任何一个入度为0的顶点,打印该顶点,并将该顶点及其相关的边从图中删除,然后对图的剩下部分重复此操作。最终打印顺序就是拓扑排序结果。
对应伪代码如下:

void topuSort(){
	for(int i=0; i<num_vertex; i++){
		//寻找图中剩余部分入度为0的顶点
		Vertex v = findNewVertexWithZeroIndegree()
		//如果没有找到入度为0的顶点,说明图中有环
		if(v == null){
			throw new Exception("Graph has cycle !")
		}
		//给顶点设置拓扑排序编号,最后此编码顺序就是拓扑排序结果
		v.topuNo = i;
		//将与v相邻的所有顶点的入度减1(从图中去掉与v相关的边)
		for each Vertex w adjacent to v
			w.indegree--;
	}
}

findNewVertexWithZeroIndegree()方法对图进行简单遍历寻找入度为0的顶点,每次调用花费O(n)时间(n为图的顶点个数),一共对该方法调用n次,所以上述代码的时间复杂度为O( n 2 n^2 n2),该代码时间复杂度较差,下面我们对其进行优化。

2、算法优化

上面的代码运行时间较差的原因在于,每个顶点的迭代都对图进行一次遍历寻找入度为0的顶点。如果是稀疏图,每次迭代只有少量顶点的入度发生变化,但是查找新的入度为0的顶点时,还是遍历了所有顶点,造成很多无效的重复操作。
可以用一个队列存放所有的入度为0的顶点,每次从队列中取一个顶点进行处理,并从队列中删除该顶点,然后更新该顶点所有相邻顶点的入度,如果更新后入度为0,则将其放入队列。
伪代码如下:

void topuSort() {
	//将入度为0的顶点存在该队列中
	Queue<Vertex> zeroVertexQueue = new Queue<Vertex>();
	//遍历图,将顶点为0的顶点存到队列中
	for each Vertex v in Graph {
		if(v.indegree == 0){
			//入队
			zeroVertexQueue.enqueue();
		}
	}
	int num = 0;
	while(!zeroVertexQueue.isEmpty()){
		//出队,从队列中获取一个顶点,并从队列中删除
		Vertex v = zeroVertexQueue.dequeue();
		//设置拓扑排序编号
		v.topuNo = num;
		num++;
		处理图中与v相邻的顶点
		for each Vertex w adjacent to v {
			w.indegree--;
			//如果入度更新后值为0,将该顶点入队
			if(w.indegree == 0){
				zeroVertexQueue.enqueue();
			}
		}
	}
	if(num != num_vertex){
		throw new Exception("Graph has cycle !")
	}
}

上面代码中,对于一个有n个顶点,m条边的图,while循环的时间复杂度为O(n);每次for循环处理邻接顶点的入度,一条边对应一个邻接顶点,故此部分时间复杂度为O(m),所以上述优化后的代码总的时间复杂度为O(m+n)。

以上就是拓扑排序的简单介绍,欢迎交流,共同学习!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值