图论 有向无环图 拓扑排序 是什么

算法 专栏收录该内容
34 篇文章 0 订阅

一、有向无环图

  • 有方向
  • 没有闭环

有向图的拓扑排序

 

二、拓扑排序

拓扑排序是将有向无环图的顶点排成一个线性序列的过程。

比如可将上图

 

三、拓扑排序步骤

1. 首先要任意选择一个没有前驱的顶点,即入度为0的点,然后将它输出。

在下面这张图中我们选择1为出发点。

有向图的拓扑排序

 

2. 删除该节点以及与它相关联的所有边,这个点的nexts里面的点入度就减少1

选择1为出发点之后,我们将它输出,并删除该节点以及与它相关联的所有边。

 

有向图的拓扑排序

 

3. 然后在删除后的图中继续找一个没有前驱的节点,

这里没有前驱的节点只有2和3.

这里我们选择3,那么将节点3输出后的图 如下图所示。

有向图的拓扑排序

 

4. 继续找入度为0的点重复上述步骤。

接下来没有前驱的节点只有2和6了。

我们这里选择节点6,同样的输出节点6后删除。

然后继续找没有前驱的节点。这时候没有前驱的节点只剩下节点2.

 

有向图的拓扑排序

接下来的点继续进行拓扑排序,

 

5. 得到的拓扑排序的一种如下图所示。

有向图的拓扑排序

 

相信大家也都发现其实拓扑排序是不唯一的,我们选择的出发点不同,结果就是不一样的。

这里给出大家针对上图几种拓扑排序序列。

有向图的拓扑排序

 

 

四、算法设计

用一个map保存他的所有节点对应的入度。

用一个队列保存每次入度为0的节点然后pop,pop的顺序就是拓扑排序的顺序。

 

list <node*> tsort(graph G) {
	list<node*> res;
	unordered_map<node*, int> inmap; 
	queue<node*> zeronode;
	for (auto next : G.nodes) {//G.nodes是map
		inmap[next.second] = next.second->in;
		if (next.second->in == 0) {
			zeronode.push(next.second);
		}
	}
	while (!zeronode.empty()) {
		node* cur = zeronode.front();
		zeronode.pop();
		res.push_back(cur);
		for (auto next : cur->nexts) {
			inmap[next]--;
			if (inmap[next] == 0) {
				zeronode.push(next);
			}
		}
	}

	return res;
 }

 

 

https://jingyan.baidu.com/article/1e5468f9c2c830094861b769.html

 

https://zhuanlan.zhihu.com/p/127190494

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值