大四复习:深入浅出解释拓扑排序

2023-12-19

我在大二学习拓扑排序的时候,不是很明白,现在已经大四,抽时间复习一下拓扑排序。

什么是拓扑排序?

如何实现拓扑排序?

拓扑排序的拓展


什么是拓扑排序?

首先拓扑排序的定义如下:

拓扑排序是一种对有向无环图的顶点进行排序的方法。它的主要目的是产生一个顶点的线性序列,使得如果在图中存在一条从顶点 A 指向顶点 B 的边,则在排序结果中,顶点 A 出现在顶点 B 之前。

什么意思呢?我的理解拓扑排序 简单的说,就是 遍历一个没有环的有向图中, 按照箭头的顺序遍历节点。

在上面一个有向无环图中,必须先访问a,才可以访问b或c;必须先访问b和c,才可以访问d。

所以,图的拓扑排序为a,b,c,d   或者a,c,b,d

如何实现拓扑排序?

这里我首先给出拓扑排序的算法,只有两步:

第一步: 访问一个入度为0的节点

第二步: 删除入度为0的节点以及从这个节点出去的所有边,继续执行1,直至图中没有节点。

以上面的图为例,a的入度为0,所以访问a,同时删除a和a的两个出边;此时,b和c节点的入度变为0。

因为b和c的入度都为0,我们可以随便选择一个访问,假设访问的b,删除b节点和它 的出边。

然后访问c节点,删除c节点和它 的出边,此时d节点入度为0,直接删除d节点,图中没有节点;

算法执行完毕。所以一个拓扑排序是  a,b,c,d。

如何来实现呢?我这里直接给出结论:使用BFS进行拓扑排序。

  1. 计算入度 :对于图中的每个顶点,计算它的入度(即有多少边指向该顶点)。

  2. 初始化队列 :创建一个队列,用于存储所有入度为 0 的顶点。这些顶点没有任何先决条件,可以立即处理。

  3. 拓扑排序

    • 当队列不为空时,从队列中移除一个顶点,并将其添加到拓扑排序的结果中。
    • 遍历该顶点的所有邻接顶点,将这些邻接顶点的入度减 1(因为它们的一个依赖已经被移除了)。
    • 如果任何邻接顶点的入度变为 0,则将其添加到队列中。
  4. 检查是否存在拓扑排序 :如果排序结果中的顶点数量不等于图中的顶点总数,则说明图中存在环,因此不存在拓扑排序。

为什么可以使用BFS呢?(BFS算法不在这里多讲了。)

BFS 以层级的方式遍历,在处理当前层的顶点之前,所有的前置顶点(即入度已被减至 0 的顶点)已经被处理。这种层级性保证了拓扑排序的正确性。

伪代码:

下面举一个具体的题目, leetcode207. 课程表

class Solution {
public:
    bool canFinish(int n, vector<vector<int>>& p) {
        vector<int>d(n,0);
        vector<vector<int>>g(n);
        for(int i=0;i<p.size();i++){
            g[p[i][0]].push_back(p[i][1]);
            d[p[i][1]]++;
        }
        queue<int>q;
        int cnt=0;
        for(int i=0;i<n;i++)if(d[i]==0)q.push(i);
        while(!q.empty()){
            int t=q.front();
            q.pop();
            cnt++;
            for(auto ne:g[t]){
                d[ne]--;
                if(d[ne]==0)q.push(ne);
            }
        }
        return cnt==n;
    }
};

上面代码使用C++来实现伪代码的功能,具体过程就不写了,和C++的语法有关系。

拓扑排序的拓展

拓扑排序的一个典型应用是解决具有依赖关系的任务调度问题。例如,在编译器中对程序模块进行编译时,必须先编译依赖模块,这种依赖关系就可以通过拓扑排序来解决。

For example, suppose foo.c calls functions in libx.a and libz.a that call functions in liby.a. Then libx.a and libz.a must precede liby.a on the command line:

unix> gcc foo.c libx.a libz.a liby.a

Libraries can be repeated on the command line if necessary to satisfy the dependence requirements. For example, suppose foo.c calls a function in libx.a  that calls a function in liby.a that calls a function in libx.a. Then libx.a must be repeated on the command line:

unix> gcc foo.c libx.a liby.a libx.a

摘自CSAPP

在编译过程中,模块间的依赖关系可以被视为一个有向图,其中每个模块代表一个顶点,依赖关系表示为有向边。例如,如果模块 A 依赖于模块 B,则会有一条从 B 指向 A 的边。

对于CSAPP的例子中,可以使用图来表示这个依赖关系:

拓扑排序还有一个重要的用途是检测循环依赖。如果模块间的依赖关系形成了一个环,那么将无法进行有效的拓扑排序。这在编译过程中是一个关键的检查点,因为循环依赖通常是编程错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大四复习:深入浅出解释拓扑排序 的相关文章

  • 安恒明御安全网关aaa_local_web_preview 任意文件上传漏洞复现

    简介 安恒明御安全网关是一个网络安全产品 由安恒信息技术股份有限公司开发和提供 它是一个综合性的安全管理平台 用于保护企业网络免受各种网络威胁的攻击 该产品aaa local web preview端点存在文件上传漏洞 漏洞复现 FOFA语
  • ​什么是纳米技术?纳米技术如何用于疾病诊断?

    为增进大家对纳米技术的认识 本文将对纳米技术 纳米技术在疾病诊断方面的应用予以介绍 纳米技术 是如今研究比较深入的技术之一 在未来 纳米技术必将为人类带来更多福利 为增进大家对纳米技术的认识 本文将对纳米技术 纳米技术在疾病诊断方面的应用予

随机推荐

  • 大创项目推荐 深度学习 python opencv 火焰检测识别 火灾检测

    文章目录 0 前言 1 基于YOLO的火焰检测与识别 2 课题背景 3 卷积神经网络 3 1 卷积层 3 2 池化层 3 3 激活函数 3 4 全连接层 3 5 使用tens
  • 【K哥爬虫普法】北京某公司惨遭黑客攻击13000000余次,连夜报警……

    我国目前并未出台专门针对网络爬虫技术的法律规范 但在司法实践中 相关判决已屡见不鲜 K 哥特设了 K哥爬虫普法 专栏 本栏目通过对真实案例的分析 旨在提高广大爬虫工程师的法律意识 知晓如何合法合规利用爬虫技术 警钟长鸣 做一个守法 护法 有
  • 漏洞复现-iDocview doc/upload接口存在任意文件读取漏洞(附漏洞检测脚本)

    免责声明 文章中涉及的漏洞均已修复 敏感信息 均已做打码处理 文章仅做 经验分享 用途 切勿当真 未授权的攻击属于非法行为 文章中 敏感信息 均已做多层打马处理 传播 利用本文章所提供的信息而造成的任何直接或者间接的后果及损失 均由使用者本
  • PageView组件实现翻页和自定义轮播图

    PageView实现上下翻页 import package flutter material dart import package flutter services dart import package flutter demo too
  • app测试必掌握的核心测试:UI、功能测试!

    一 UI测试 UI即User Interface 用户界面 的简称 UI 设计则是指对软件的人机交互 操作逻辑 界面美观的整体设计 好的UI设计不仅是让软件变得有个性有品味 还要让软件的操作变得舒适 简单 自由 充分体现软件的定位和特点 手
  • CMD命令入门指南:从零开始学习基本命令

    在计算机的日常使用中 我们经常需要使用命令行来执行一些特定的任务 而在Windows操作系统中 CMD命令是最常用和最基本的命令行工具 本文将为您介绍如何从零开始学习基本的CMD命令 帮助您快速上手并提高计算机的使用效率 首先 让我们了解一
  • 谁能想到Java多线程设计模式竟然能被图解,大佬就是大佬,太牛了

    设计模式 Design pattern 代表了最佳的实践 通常被有经验的面向对象的软件开发人员所采用 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案 这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的
  • python程序打包成exe全流程纪实(windows)

    目录 前言 准备工作 安装python 必须 安装vs平台或conda 非必须 详细步骤 Step1 创建python虚拟环境 方法一 裸装 windows下
  • 不敢置信,某位大佬上传Mybatis学习笔记,让你轻松从入门到精通

    MyBatis简介 MyBatis是一款优秀的开源持久层框架 支持自定义SQL查询 存储过程和高级映射 目前在Github上已有17k Star 在MyBatis中 我们可以在XML中编写SQL语句 然后绑定到Java方法中 通过参数和结果
  • Linux值得学习吗?打工人利用业务时间学习Linux需要多长时间?

    nbsp Linux值得学习吗 打工人利用业务时间学习Linux需要多长时间 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Linux的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评
  • 对于template标签中的多个v-if的li标签的问题

    问题 section class grid main div class grid div ul ul div section
  • 视频提取文字用什么软件好?来试试下面这几款吧

    听说你找不到识别字幕的插件 没问题 我这就来给你支招 其实识别字幕不一定得使用插件 许多软件也可以帮助你将视频内容识别出来 而且 世界上的字幕识别软件可不少呢 有的品质过硬 声名显赫 还有的藏着各种神奇的功能和特色 那么 你看到这里是否想知
  • 什么是过载?什么是过流?

    目录 过载是什么 过流是什么 过载保护 过电流保护 短路保护 过载是什么 在电网或者是我们的日常生活中所用到的每一个电气设备都会有一个额定功率 当设备的功率比额定功率高的时候我们称为过载 同样地 我们将对这种超过额定功率的保护称为过载保护
  • 外包干了5个月,技术退步太明显了。。。。。

    先说一下自己的情况 本科生生 18年通过校招进入武汉某软件公司 干了差不多4年的功能测试 今年国庆 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了5个月的功能测试 已经让我变得不思进取 谈了2年的
  • 说一下 jvm 有哪些垃圾回收算法?

    说一下 jvm 有哪些垃圾回收算法 一 对象是否已死算法 1 引用计数器算法 2 可达性分析算法 二 GC算法 1 标记清除算法 如果对象被标记后进行清除 会带来一个新的问题 内存碎片化 如果下次有比较大的对象实例需要在堆上分配较大的内存空
  • JMeter如何从数据库中获取数据并作为变量使用?

    前言 JMeter 如何从数据库中获取数据并作为变量使用 这在我们使用 JMeter 做 接口测试 压力测试 时经常碰到 今天通过两个示例 实现MySQL数据库的查询结果的 单值引用 和 多值引用 进行说明 这里虽然以MySQL数据库做说明
  • mybatis.interceptor.exception.SqLValidateException:Ilegal SQL::......

    现象 描述 执行 SQL 没问题 应用代码报错 mybatis interceptor exception SqLValidateException Ilegal SQL SELECT voucherNo FROM voucher ORDE
  • Java18都在路上了,你还在用Java8吗?

    Java18都在路上了 你还在用Java8吗 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Java的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评论区回复 888 之后私信回复 8
  • 利用阿里云的尖端数据库解决方案增强游戏数据管理

    在快节奏和动态的游戏世界中 对于努力为玩家提供无缝体验的公司来说 管理大量数据是一项关键挑战 阿里云是亚太地区的主要参与者 也是全球公认的运营数据库管理系统领导者 提供量身定制的创新解决方案 以应对游戏公司面临的独特数据管理挑战 这篇博客探
  • 大四复习:深入浅出解释拓扑排序

    我在大二学习拓扑排序的时候 不是很明白 现在已经大四 抽时间复习一下拓扑排序 什么是拓扑排序 如何实现拓扑排序 拓扑排序的拓展 什么是拓扑排序 首先拓扑排序的定义如下 拓扑排序是一种对有向无环图的顶点进行排序的方法 它的主要目的是产生一个顶