拓扑排序图解-Kahn算法和深度优先搜索

拓扑排序 是将一个有向无环图中的每个节点按照依赖关系进行排序。比如图 G G G存在边 < u , v > <u,v> <u,v> 代表 v v v的依赖 u u u, 那么在拓扑排序中,节点 u u u一定在 v v v的前面。

从另一个角度看,拓扑排序是一种图遍历,具有两个性质:

  • G G G中的每个节点 v v v在排序序列中仅出现一次。
  • 节点 v v v当且仅当其依赖的所有节点 u u u被访问完成,才被访问。

拓扑排序能够在 O ( V + E ) O(V+E) O(V+E)的线性时间内完成,分为两种算法-Kahn算法和深度优先搜索

拓扑排序实例

在这里插入图片描述
这个图有很多有效的拓扑排序,包括:

视觉从左到右,从上到下:

5, 7, 3, 11, 8, 2, 9, 10

最小编号的可用顶点优先:

3, 5, 7, 8, 11, 2, 9, 10

按入边邻居的字典顺序:

3, 5, 7, 8, 11, 2, 10, 9

最少边数优先:

5, 7, 3, 8, 11, 2, 10, 9

最大编号的可用顶点优先:

7, 5, 11, 3, 10, 8, 9, 2

尝试从上到下,从左到右:

5, 7, 11, 2, 3, 8, 9, 10

任意顺序:

3, 7, 8, 5, 11, 10, 2, 9

Kahn算法

L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edgewhile S is not empty doremove a node n from Sadd n to Lfor each node m with an edge e from n to m doremove edge e from the graphif m has no other incoming edges theninsert m into Sif graph has edges thenreturn error   (graph has at least one cycle)
else return L   (a topologically sorted order)

这个算法的思想是:

  • 首先,在非空的有向无环图中,找到一组没有入边的起始节点,并将它们插入一个集合 S。上节图中的3,5,7 都是起始节点。
  • 从S取出一个节点 n n n,追加到列表L
  • 对于每个依赖节点 n n n的节点 m m m, 删除边 < n , m > <n,m> <n,m>
  • 如果节点 m m m变成起始节点,即入度为0, 那么加入集合S.
  • 最后如果图中还有未删除的边,那说明图存在环路,无法拓扑排序;否则输出拓扑排序序列

算法依据的原理是什么?

无环图的正常遍历情况是这样的:

黄色代表集合S中的节点

在这里插入图片描述

有环图的情况:

如果图G中有环,遍历至环路中任一节点,因为无法在环路中,找到任何一个开始节点进入环路,导致S为空,算法中止。
在这里插入图片描述

深度优先搜索

L ← Empty list that will contain the sorted nodes
while exists nodes without a permanent mark doselect an unmarked node nvisit(n)function visit(node n)if n has a permanent mark thenreturnif n has a temporary mark thenstop   (graph has at least one cycle)mark n with a temporary markfor each node m with an edge from n to m dovisit(m)remove temporary mark from nmark n with a permanent markadd n to head of L

Kahn算法会破坏原来图的数据,而深度优先不会。深度优先算法采取的是标记方式探测环路。

注意到节点 n n n, 是添加到列表头部,因为是深度优先搜索,节点 n n n带永久标记代表从 n n n出发的能访问到的节点都被访问了,
即所有依赖节点 n n n的节点都已在列表里了。

无环路情况

  • 绿色为永久标记,代表从此节点出发的能访问到的节点都被访问了
  • 橙色为临时标记

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

环路情况:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/584434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《别让猴子跳回背上》——管理者的时间管理

讲时间管理的书很多&#xff0c;但这本是专门讲给管理者的时间管理。 在职场中&#xff0c;许多管理者都会碰到工作计划执行不下去、组织目标难于实现的问题&#xff0c;搭进了自己所有可以支配的时间&#xff0c;仍旧是焦头烂额&#xff0c;顾此失彼&#xff1b;而下属则因为…

力扣题目学习笔记(OC + Swift)19. 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 此题目为链表题&#xff0c;拿出我们的杀手锏&#xff0c;链表解题经典三把斧&#xff1a; 哑巴节点栈快慢指针 关于内存问题&#xff1a;由于Swift及…

算法基础day1

归并排序模版 #include <iostream> using namespace std; int n; const int N 1e610; int q[N],tmp[N]; void merge_sort(int l,int r,int q[]){if(l>r) return;int mid lr>>1;merge_sort(l,mid,q);merge_sort(mid1,r,q);//归并的的过程int k0,il,jmid1;while(…

【Vue2+3入门到实战】(10)Vue基础之一文掌握 组件通信 详细示例(组件通信语法、父传子 、 子传父、非父子通信)

这里写自定义目录标题 一、学习目标1.组件通信2.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09; 二、组件通信1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 三、…

FME之读取文件名路径FilenamePartExtractor转换器

在读取文件所在路径及相关信息时&#xff0c;我们除了在读模块时选择Directory and File Pathnames数据类型。还可以选择在某个阶段使用FilenamePartExtractor转换器来读取文件所在路径及相关信息。 在前面转换器只要暴露有fme_dataset&#xff0c;在源文件名选择它即可实现。…

Google Play上架:2023年度总结报告

今天是2023年的最后一个工作日&#xff0c;今天用来总结一下2023年关于谷歌商店上架的相关政策改动和对应的拒审解决方法。 目录 政策更新与改动2023 年 2 月 22 日2023 年 4 月5 日2023 年 7 月 12 日2023 年 10 月 25 日 开发者计划政策拒审邮件内容和解决办法 政策更新与改…

利用Pandas进行高效网络数据获取

利用Pandas进行高效网络数据获取 背景&#xff1a; ​ 最近看到一篇关于使用Pandas模块进行爬虫的文章&#xff0c;觉得很有趣&#xff0c;这里为大家详细说明。 基础铺垫&#xff1a; ​ pd.read_html pandas 库中的一个函数&#xff0c;用于从 HTML 页面中读取表格数据并…

数据库 基础面试第一弹

1. SQL语句类型 1. DDL&#xff08;Data Definition Language&#xff0c;数据定义语言&#xff09;&#xff1a; DDL语句用于定义数据库对象&#xff08;如表、索引、视图等&#xff09;。常见的DDL语句包括&#xff1a; CREATE&#xff1a;用于创建数据库对象&#xff0c;如…

【网络安全 | Misc】Training-Stegano-1

该题考察winhex工具使用 打开文件&#xff1a; 使用StegSolve并不能获取有效信息 使用winhex得到flag steganoI

【Linux系统化学习】进程终止的奥秘

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Liunx系统化学习 代码仓库&#xff1a;Gitee 目录 获取函数返回值 退出码 进程退出的场景 错误码 信号终止异常代码 进程的终止 main函数直接return exit函数 _exit函数 获取函数返回值 在C语言学…

玩转区域流量调配,详细解析GLSB是什么?

在互联网早期&#xff0c;由于网络不是很发达&#xff0c;流量也相对比较小&#xff0c;单体架构已经能足够满足需求。但伴随着互联网越来越&#xff0c;网站的流量请求甚至能达到上千亿。为了实现高可用&#xff0c;需要用到多台机器来提升处理流量的能力。在这种环境下&#…

PIE-Engine简介

PIE-Engine&#xff0c;是航天宏图基于云计算、物联网、大数据和人工智能技术自主研发的一站式地球科学大数据实时计算平台&#xff0c;平台构建了基于云原生的并行高效底层架构&#xff0c;助力地球科学应用的产业化发展。&#xff08;摘自官网&#xff09; 前天&#xff0c;我…

web前端开发网页制作html/css结课作业

效果图展示&#xff1a; 注意事项&#xff1a; 引用JQuery文件地址和图片地址要更换一下。 百度网盘链接&#xff1a; http://链接&#xff1a;https://pan.baidu.com/s/1wYkmLr7csjBwQY6GmlYm4Q?pwd4332 提取码&#xff1a;4332 html界面展示&#xff1a; main.css代码部…

写给工作6年的程序员的一封信

准大牛 &#xff1b;兄&#xff0c; 希望你不会反感我给你的这个特别的称号&#xff0c;我们程序员中的大部分工作到5~6年这个节骨眼上&#xff0c;不出意外的话…准大牛…了&#xff0c;此时的你技术能力正在成熟或者已然成熟&#xff1b;架构设计力初现峥嵘&#xff1b;创新能…

Linux中磁盘管理与文件系统

目录 一.磁盘基础&#xff1a; 1.磁盘的结构&#xff1a; 2.硬盘的数据结构&#xff1a; 3.硬盘存储容量 &#xff1a; 4.硬盘接口类型&#xff1a; 二.MBR与磁盘分区&#xff1a; 1.MBR的概念&#xff1a; 2.硬盘的分区&#xff1a; 为什么分区&#xff1a; 2.表示&am…

10-让Java性能提升的JIT深度剖析

文章目录 JVM的语言无关性解释执行与JITC1、C2与Graal编译器C1编译器C2编译器 分层编译(了解即可)热点代码热点探测方法调用计数器回边计数器 编译优化技术方法内联锁消除标量替换逃逸分析技术逃逸分析的原理逃逸分析 JVM的语言无关性 跨语言&#xff08;语言无关性&#xff0…

浅谈技术架构的演进过程

前言 最近在学习Redis、Doctor相关技术知识&#xff0c;它们与分布式系统有着很大的关系。 而对于分布式系统&#xff0c;它本身就是随着业务的不断推进&#xff0c;技术架构不断演进而得到发展和实现的。而所谓的分布式系统&#xff0c;实际上就是想办法引入更多的硬件资源&am…

python 异步Web框架sanic

我们继续学习Python异步编程&#xff0c;这里将介绍异步Web框架sanic&#xff0c;为什么不是tornado&#xff1f;从框架的易用性来说&#xff0c;Flask要远远比tornado简单&#xff0c;可惜flask不支持异步&#xff0c;而sanic就是类似Flask语法的异步框架。 github&#xff1…

系统学习Python——装饰器:函数装饰器-[装饰器状态保持方案:外层作用域和全局变量]

分类目录&#xff1a;《系统学习Python》总目录 闭包函数&#xff08;带有外围def作用域引用和嵌套的def&#xff09;常常可以实现相同的效果&#xff0c;特别是用于像被装饰的最初咱数这样的静态数据时。然而在下面这个例子中&#xff0c;我们也需要外层作用域中的一个计数器&…

{MySQL} 数据库约束 表的关系 新增删除 修改 查询

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库约束1.1约束类型&#xff1a;1.2 NULL约束1.3unique 唯一约束1.4 DEFAULT&#xff1a;默认值约束1.5 PRIMARY KEY&#xff1a;主键约束1.6 FOREIGN K…