拓扑排序图解-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 edge

while S is not empty do
    remove a node n from S
    add n to L
    for each node m with an edge e from n to m do
        remove edge e from the graph
        if m has no other incoming edges then
            insert m into S

if graph has edges then
    return 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 do
    select an unmarked node n
    visit(n)

function visit(node n)
    if n has a permanent mark then
        return
    if n has a temporary mark then
        stop   (graph has at least one cycle)

    mark n with a temporary mark

    for each node m with an edge from n to m do
        visit(m)

    remove temporary mark from n
    mark n with a permanent mark
    add n to head of L

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

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

无环路情况

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

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

环路情况:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Poe会员开通保姆级教程

1 为何选择Poe&#xff1f; 原因如下&#xff1a; 免费版每天可以试用GPT4一次&#xff1b;会员版每月能发送600条GPT-4和1000条Claude消息&#xff1b;月费为19.99美元&#xff0c;年费为199.99美元&#xff0c;与ChatGPT Plus的费用几乎一致&#xff1b;背景稳固&#xff0c…

Windows iscsi

题目&#xff1a;Windows ISCSI 创建100G的ISCSI磁盘&#xff0c;存储到F盘目录下的iSCSI文件夹。 启用Mutual CHAP认证。 DCSERVER为iSCSI客户端&#xff0c;连接成功后&#xff0c;格式化挂载到F盘。 IspSrv端配置 安装ISCSI服务 配置ISCSI服务 DCSERVER端配置 发起ISC…

ESD和TVS管的区别

ESD和TVS管的区别 首先说ESD和TVS管都属于保护器件。ESD全称为Electro-Staticdischarge&#xff0c;叫做静电放电保护二极管&#xff1b;TVS全称为Transient Voltage Suppressors&#xff0c;叫做瞬变电压抑制二极管。 ESD和TVS的区别主要在功率、应用场合和封装。 ESD的保护…

BUUCTF——Reverse——新年快乐

1、题目 2、工具 Exeinfo PE&#xff1a;查壳工具。万能脱壳工具 ​​​​​​​IDA&#xff1a;是一款功能强大的反汇编工具&#xff0c;用于分析和逆向工程二进制文件。 3、题目 下载压缩包并解压&#xff0c;得到一个.exe文件。 打开文件&#xff0c;要求输入flag&#x…

java爬虫技术之Selenium爬虫

目录 前言 一、什么是代理IP&#xff1f; 二、为什么要使用代理IP&#xff1f; 三、使用Selenium爬虫结合代理IP进行爬取 1. 安装Selenium和浏览器驱动 2. 导入相关库和模块 3. 设置代理IP 4. 访问目标网页 5. 提取数据 6. 关闭浏览器驱动 四、总结 前言 Selenium爬…

Mybatis三 | 动态SQL

目录 if where set ctrl alt l格式化SQL语句 随着用户的输入或外部条件的变化而变化的SQL称为动态SQL if <if>用来判断条件是否成立&#xff0c;使用test属性进行条件判断&#xff0c;如果true&#xff0c;则拼接SQL where wehre元素只会在有条件成立的情况下才插入…

Leaning Method

001用分布在两个地方的两台办公电脑开发一个项目&#xff0c;计划使用gitee同步代码。具体应该怎么操作&#xff1f; 要使用 Gitee 同步代码&#xff0c;你可以按照以下步骤进行操作&#xff1a; 在两台办公电脑上都安装 Git 客户端&#xff0c;并在 Gitee 上创建一个项目仓库…

C语言——字符函数和字符串函数(三)【strtok,strerror,perror】

&#x1f4dd;前言&#xff1a; 上一篇文章C语言——字符函数和字符串函数&#xff08;二&#xff09;对字符函数和字符串函数strstr&#xff0c;strcmp和strncmp进行了一定的讲解 这篇文章主要讲解以下函数的用法: 1&#xff0c;strtok 2&#xff0c;strerror 3&#xff0c;pe…

AI工程化与低代码:加速人工智能应用开发的新趋势

随着人工智能&#xff08;AI&#xff09;技术的广泛应用&#xff0c;AI工程化在开发领域中变得越来越重要。而低代码开发平台的出现&#xff0c;进一步加速了AI应用的开发和部署过程。本文将介绍AI工程化的概念&#xff0c;探讨低代码如何助力开发者快速构建和部署AI应用&#…

C# 读取Word表格到DataSet

目录 功能需求 Office 数据源的一些映射关系 范例运行环境 配置Office DCOM 关键代码 组件库引入 ​核心代码 杀掉进程 总结 功能需求 在应用项目里&#xff0c;多数情况下我们会遇到导入 Excel 文件数据到数据库的功能需求&#xff0c;但某些情况下&#xff0c;也存…

WinSCP本地安装部署并结合内网穿透实现远程连接服务器

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默…

知行合一:投资篇

这是一个系列的内容。 是学习。 是沉淀。 是分享。 是反思。 是财务自由的梦想。 已完成&#xff1a; 1.1 编程基础   1.1.1 投资-编程基础-numpy todo… 下面是长期的xmind计划&#xff0c;会根据已经整理的内容逐步完善:

记录 | ubuntu安装nginx

1. 安装依赖 sudo apt-get install libpcre3 libpcre3-devsudo apt-get install zlib1g-devsudo apt-get install openssl libssl-dev 在安装 libssl-dev 的时候若出现报错&#xff1a; 【解决办法】   降级 libssl 解决依赖关系&#xff0c;通过 aptitude 安装&#xff1a;…

【Spring】SpringBoot 配置文件

文章目录 什么是配置文件SpringBoot配置文件配置文件快速入手配置文件的格式properties 配置文件说明properties 基本语法读取配置文件信息properties 配置格式缺点 yml 配置文件说明yml 基本语法使用 yml 连接数据库 yml 使用进阶yml 配置不同数据类型配置对象配置集合配置Map…

构建外卖系统:从技术到实战

在当今高度数字化的社会中&#xff0c;外卖系统的开发变得愈发重要。本文将从技术角度出发&#xff0c;带领读者一步步构建一个基础的外卖系统&#xff0c;并涵盖关键技术和实际代码。 1. 技术选型 1.1 后端开发 选择Node.js和Express框架进行后端开发&#xff0c;搭建一个灵…

Java框架基础--maven,http,postman

maven Maven 提供了一个标准的构建生命周期和一组约定的目录结构&#xff0c;以简化和规范项目的构建过程。它主要用于 Java 项目&#xff0c;但也可以用于其他类型的项目。提高了项目的可维护性、可重复性和一致性&#xff0c;简化了构建和依赖管理的复杂性&#xff0c;使得开…

docker-compose部署openldap

前段时间在本地搭建了一套gitlab geo测试环境&#xff0c;因为需要集成ldap&#xff0c;所以特意搭建下&#xff0c;特此作为笔记记录下。 文章目录 1. 前置条件2. 编写docker-openldap.yml文件3. 登录4. 使用创建组创建用户登录测试 1. 前置条件 安装docker-compose 安装docke…

python 用hyperlpr3 进行车牌识别

开源项目 https://github.com/zeusees/HyperLPR 下面按装相关的模块 pip install opencv-python pip install hyperlpr3 pip install cvlib代码 download_image_from_url 将网上图片存本地。 import urllib.request import cv2 import hyperlpr3 as lpr3 import matplotlib.…

Gateway集成方法以及拦截器和过滤器的使用

前提&#xff1a;请先创建好一个SpringBoot项目 1. 引入依赖 SpringCloud 和 alibabaCloud 、 SpringBoot间对版本有强制要求&#xff0c;我使用的springboot是3.0.2的版本。版本对应关系请看&#xff1a;版本说明 alibaba/spring-cloud-alibaba Wiki GitHub <dependency…

windows安装npm教程

NPM&#xff08;Node Package Manager&#xff09;是一个用于管理和共享JavaScript代码包的工具。它是Node.js生态系统的一部分&#xff0c;广泛用于构建JavaScript应用程序和库。 以下是NPM的主要功能和用途&#xff1a; 1.代码包管理 NPM允许开发者在项目中安装、更新、卸载…