有向图 G=(V,E)G=(V,E)G=(V,E) 的拓扑排序

拓扑排序概念

拓扑排序是针对有向图而言的,无向图中不存在拓扑排序的概念。所谓拓扑排序,即为有向图中全部顶点的一种线性排序。这个线性排序结果需要满足一定的条件,即对于有向图中的任意两个顶点uuu和vvv,若图中存在有向边u→vu \rightarrow vu→v,则在拓扑排序结果中顶点uuu一定位于vvv的前面。

那么,由拓扑排序的概念可以推出,只有有向图中入度为0的顶点才能成为拓扑排序的第一个顶点。这个原则也是解决有向图拓扑排序的一个指导性原则。

AOVAOVAOV网络

由于存在一些概念上的联系,这里简单插入介绍一下AOVAOVAOV网络的概念。
Activity On Vertex Network,顶点表示活动,边表示活动间的先后关系的网络图。拓扑排序是对AOVAOVAOV网络的一种简化或者调度活动的执行顺序的过程。

由于网络中,不同的活动之间可能存在相互依赖,因此拓扑排序最终给出了一种合理地调度活动执行的先后顺序。如果所有活动之间存在着一种或多种合理的顺序,能够顺利完成全部活动,则表明该AOVAOVAOV网络为有向无回路图或有向无环图。若某个活动A依赖活动B,而活动B又依赖活动A,则表明AOVAOVAOV网络存在回路或向环。因此无法合理的完成全部活动。

拓扑排序方法

那么,如何确定一个有向图是否具有拓扑排序,也即是确定一个有向图是否存在回路或环呢?这里给出执行拓扑排序的方法:
不断重复地寻找入度为0的顶点,执行如下操作:首先将该顶点作为拓扑排序的输出结果,然后将该顶点及顶点关联的出边从图中删去。循环结束条件为:所有的顶点都已搜索完毕,或着顶点未搜索完,但是顶点的入度不为0,无法删除。

解释一下

入度(inDegree):顶点的入度表示有向图中以该顶点为终点的边的个数;出度(outDegree):顶点的出度表示有向图中以该顶点为起点的边的个数。因此,所谓的顶点的出边是指以顶点为起点的边。

由拓扑排序推出的原则可知,拓扑排序的第一个顶点即为入度为0的点,那么在有向图中删除该顶点后的构成的新图,重复地进行拓扑排序即可得到最终的拓扑排序结果。

具体到解决问题的方法上,我们直到关于图的搜索一般有两种方式:广度优先搜索和深度优先搜索。

广度优先搜索步骤

  1. 定义inDegree用于存储搜索过程中每一个顶点的入度。
  2. 遍历一边图的邻接表,将每一个顶点的邻接表转化为对应顶点的入度。
    具体地,对于一条有向边u→vu \rightarrow vu→v,则inDegree(v) += 1。
  3. 选择入度为0的顶点开始搜索,将顶点作为拓扑排序输出。
  4. 对于已经完成搜索的顶点,更新其邻接表中顶点的入度,值减一。
  5. repeat 3,4,until 循环结束条件。
  6. 循环结束条件:a、搜索完有向图中全部顶点,b、无法完成全部顶点的搜索。
  7. 满足条件a时,表明有向图存在拓扑排序结果;满足条件b时,则表明该有向图存在回路或环,不存在拓扑排序。

BFS Pseudocode

edgesedgesedges 邻接表集合
inDegreesinDegreesinDegrees 顶点的入度集合
bfsQbfsQbfsQ 搜索队列,存放入度为0的顶点
topoListtopoListtopoList 存储拓扑排序结果

BFS(G(V, E))//初始化for u in G(V)for v in edges(u)do inDegrees(v) += 1//放入入度为0的顶点for degree in inDegreesdo if degree == 0 thenbfsQ.push(i);//循环搜索while bfsQ not empty do//搜索到入度为0的顶点vertex = bfsQ.pop//插入到拓扑排序结果中topoList.add(vertex)//搜索顶点vertex的邻接表for v in edges(vertex)//更新顶点v的入度值inDegrees(v) -= 1do if inDegrees(v) == 0//顶点入度减为0时添加待搜索队列中then bfsQ.push(v)//搜索结束后,判断结束条件//当拓扑排序结果为全部的顶点时,表明满足循环结束条件a,否则满足循环结束条件b。return topoList.size() == |V| ? topoList: 0;

深度优先搜索步骤

DFS在搜索过程中顶点具有三种状态:未搜索(0),搜索中(1),已搜索(2)。
三种状态的含义如下:
未搜索(0):表示搜索过程中该顶点尚未被发现,属于一个新顶点,
搜索中(1):表示该顶点已被发现, 但其邻接顶点还尚未被搜索完,
已搜索(2):表示该顶点及其邻接顶点都完成搜索。

DFS Pseudocode

edgesedgesedges 邻接表集合
visitedvisitedvisited 用于保存顶点的搜索状态
SSS 栈,保存拓扑排序结果

algorithm for DFS(G(V,E))//初始化visitedfor u in V[G]do visited(u) = 0for u in V[G]do if visited(u) == 0 then//深度优先搜索全部的顶点DFS(u)拓扑排序结果为S出栈的顺序,原因是先完成搜索的顶点存放到栈的底部DFS(u)//顶点的状态设为搜索中do visited(u) = 1for v in edges(u)//深度优先的方式进行邻接表的搜索do if visited(v) == 0 then//遇到未搜索状态的顶点,继续进行深度优先搜索DFS(u)do if visited(v) == 1 then//遇到搜索中状态的顶点,说明此前该顶点已经在这条深度优先搜索路径中出现两次//这里表明有向图中存在回路或环do if visited(v) == 2 then//pass 不重要的trivial//到这里说明顶点u已经完成深度优先搜索,更新其搜索状态为已搜索visited(u) == 2//入栈S.push(u)

典型的应用

力扣题解-207. 课程表
力扣题解-210. 课程表 II

有向图 G=(V, E) 的拓扑排序相关推荐

  1. ACM 模板--邻接表 有向图 拓扑排序

    /*** C++: 无回路有向图(Directed Acyclic Graph)的拓扑排序* 该DAG图是通过邻接表实现的. ** @author judyge* @date 2014/04/22*/ ...

  2. 有向图的拓扑排序算法JAVA实现

    一,问题描述 给定一个有向图G=(V,E),将之进行拓扑排序,如果图有环,则提示异常. 要想实现图的算法,如拓扑排序.最短路径--并运行看输出结果,首先就得构造一个图.由于构造图的方式有很多种,这里假 ...

  3. 如何生成有向图_八十六、从拓扑排序探究有向图

    「@Author:Runsen」 关于排序,其实还有很多,比如常见的希尔排序,桶排序,计数排序和基数排序,由于要过渡到数据结构有向图,因此需要了解拓扑排序和邻接矩阵概念. 拓扑排序 拓扑排序本身并不是 ...

  4. 拓扑排序之java实现_有向图和拓扑排序Java实现

    package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...

  5. C/C++二级指针概念及应用(有向图的邻接表(拓扑排序)、有向网图的邻接表、树的孩子表示)

    目录 一.概述 例1: 例2: 代码: 二.实例 1.有向图的邻接表(拓扑排序) 2.有向网图的邻接表 3.树的孩子表示 一.概述 二级指针:指向指针的指针.一般需要修改地址的时候会用到二级指针. 注 ...

  6. Problem G. Graph 2015-2016 acmicpc neerc 拓扑排序模拟

    一道好题 题目详见题目连接G graph 显然模拟拓扑排序的步骤是必不可少了. 假设我们当前有t个点,他们的入度均为0.我们不知道该选取哪一个. 我们把这t个点按从小到大排好序(放入小顶堆),假设我们 ...

  7. 八十六、从拓扑排序探究有向图

    @Author:Runsen 关于排序,其实还有很多,比如常见的希尔排序,桶排序,计数排序和基数排序,由于要过渡到数据结构有向图,因此需要了解拓扑排序和邻接矩阵概念. 拓扑排序 拓扑排序本身并不是一个 ...

  8. aov建立Java模拟,数据结构之---C语言实现拓扑排序AOV图

    //有向图的拓扑排序 //杨鑫 #include #include #include #define MAX_NAME 3 #define MAX_VERTEX_NUM 20 typedef int ...

  9. 拓扑排序(Topology_Sort)

    基本思想 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序 ...

最新文章

  1. Framework 4.0 新关键字dynamic 之我见(二)
  2. UPDATE STATISTICS 有何妙用?
  3. python心得体会-终于懂得python基础学习心得
  4. brew 安装java8_mac使用brew安装Java8
  5. python是偏向bs还是cs_CS与BS架构区别、比较、及现状与趋势分析
  6. DFS+BFS(POJ3083)
  7. Axure+SVN——实现多人团队开发
  8. 【Linux】Linux根据文件路径查找索引节点
  9. 3D控件Aspose.3D 12月新版V17.12发布 | 添加支持导出RVM
  10. 20sccm_SCCM安装及配置过程总结
  11. 仅训练996个剧本,迪士尼用AI自动生成动画
  12. 数学基础_若要使骰子(六个面)的每个数都出现至少一次,那么平均需要掷多少次骰子?
  13. graphql_GraphQL简介
  14. dd命令(dd命令制作镜像)
  15. 《朗读者》的读后感优秀范文4000字
  16. 中高级前端工程师都需要熟悉的技能--前端缓存
  17. linux对笔记本,联想转变对Linux笔记本态度更认真对待
  18. LeetCode部分习题解答记录-动态规划
  19. 如何快速的找到动漫,电影资源
  20. mysql关联表删除、修改数据

热门文章

  1. linux上的客户端连接window上的服务器
  2. python解一元二次方程复数_python – SymPy和复数的平方根
  3. 电子招标投标系统 —采购招投标管理一体化系统-
  4. Unity接口的使用
  5. 商家招牌的分类与检测
  6. 高端装备的AC主轴头结构
  7. 操作系统镜像下载【windows+linux+mac】
  8. 文件复制 要求边读边写
  9. logistic函数,sigma函数性质
  10. HIDS入侵检测能力评估list