如果图中存在环(回路),那么该图不存在拓扑排序,在这里我们讨论的都是无环的有向图。

什么是拓扑排序

一个例子

对于一部电影的制作过程,我们可以看成是一个项目工程。所有的工程都可以分为若干个"活动"的自工程。在这些活动之间,通常会受到一定的条件约束,如其中某些活动必须在另一些活动完成之后才能开始。比如,电影制作不可能在人员到位进驻场地时,导演还没有找到,也不可能在拍摄过程中,场地都没有。这些听起来就很荒谬。

在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,称为AOV网(Activity On Vertex Network)。
AOV网中的弧表示活动之间存在的某种制约关系。

设G={V, E}是一个具有n个顶点的有向图,V中的顶点序列v1v_1v1​,v2v_2v2​,…,vnv_nvn​满足若从顶点viv_ivi​到vjv_jvj​有一条路径,则在顶点序列中顶点viv_ivi​必在顶点vjv_jvj​之前。则我们成这样的顶点序列为一个拓扑序列。
摘自:《大话数据结构》

那么拓扑排序,其实就是对一个有向图构造拓扑序列的过程。构造时有两个结果:

  1. 如果此网的全部顶点都被输出,说明该网是不存在环的AOV网
  2. 如果输出的顶点数少了,说明这个网存在环,不是一个AOV网

算法思路

从AOV网中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧。继续重复此步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止。

算法实现

数据结构

由于拓扑排序中,需要删除顶点,那么采用邻接矩阵的方式就不太合适,我们可以使用邻接表,这样会更方便。
在算法运行过程中,始终要查找入度为0的顶点,我们在原来顶点表结构的基础上,增加一个入度域in,表示该顶点入度的数字。
边表节点结构体:

public class EdgeNode {int adjevex;int weight;EdgeNode next;public EdgeNode(int adjevex, EdgeNode next) {this.adjevex = adjevex;this.next = next;}
}

顶点表节点结构体:

public class VertexNode {int in;Object data;EdgeNode firstedge;public VertexNode(Object data, int in, EdgeNode firstedge) {this.data = data;this.in = in;this.firstedge = firstedge;}
}

示例AOV图:

对应的邻接表为:

在算法中,我们还需要使用到一个,用来存储处理过程中入度为0的顶点下标,目的是为了避免每次查找时都需要遍历顶点表找有没有入度为0的顶点。

拓扑算法代码实现:

package 拓扑排序;import java.util.Stack;public class TopologySort {static VertexNode[] adjList;Stack stack = new Stack();public String ToplogicalSort() {EdgeNode e;int k, gettop;int count = 0;for (int i = 0; i < adjList.length; i++) {if(adjList[i].in  == 0) {stack.push(i);}}while(!stack.empty()) {gettop = (int) stack.pop();System.out.print(adjList[gettop].data + "->");count++;for (e = adjList[gettop].firstedge; e != null; e = e.next) {k = e.adjevex;if((--adjList[k].in) == 0) {   //将其入度减少一位,目的是将顶点上的弧删除stack.push(k);}}}System.out.println();return count < adjList.length ? (String) "ERROR" : (String) "OK";}public static EdgeNode getAdjvex(VertexNode node) {EdgeNode e = node.firstedge;while(e != null) {if(e.next == null) break;elsee = e.next;}return e;}public static void main(String[] args) {int[] ins = {0, 0, 2, 0, 2,3,1,2,2,1,1,2,1,2};int[][] adjvexs = {{11, 5, 4},{8,4,2},{9, 6, 5},{13, 2},{7},{12, 8},{5},{},{7},{11, 10},{13},{},{9},{}};adjList = new VertexNode[ins.length];for (int i = 0; i < ins.length; i++) {adjList[i] = new VertexNode("V"+i, ins[i],null);if(adjvexs[i].length > 0) {for (int j = 0; j < adjvexs[i].length; j++) {if(adjList[i].firstedge == null) adjList[i].firstedge = new EdgeNode(adjvexs[i][j], null);else {getAdjvex(adjList[i]).next = new EdgeNode(adjvexs[i][j], null);}    }}}TopologySort t = new TopologySort();System.out.println(t.ToplogicalSort());}}

该算法的时间复杂度为O(n+e)。

转载于:https://www.cnblogs.com/lishanlei/p/10707810.html

有向图的拓扑排序的理解和简单实现(Java)相关推荐

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

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

  2. 在linux下实现拓扑排序,数据结构——有向图(拓扑排序算法)

    package zieckey.datastructure.study.graph; /** * 有方向图 * * @author zieckey */ public class DirectedGr ...

  3. Java实现有向图的拓扑排序

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

  4. 数据结构之图:有向图的拓扑排序,Python代码实现——26

    有向图的拓扑排序 拓扑排序介绍 什么是拓扑排序? 一个有向图的拓扑排序(Topological sort 或 Topological ordering)是根据其有向边从顶点U到顶点V对其所有顶点的一个 ...

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

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

  6. (数据结构)有向图的拓扑排序 Kahn算法

    拓扑排序是对有向无圈图的顶点的一种排序,使得如果存在一条从vi到vj的路径,那么在排序中,vi必须出现在vj的前面. 首先,我们需要准备一个vector<int> link[maxn],l ...

  7. AOV网络(有向图)----拓扑排序--判断有无环的问题--12月18日

    AOV网络 用顶点表示活动的网络 用有向图表示先修和后修的关系. 在有向图中,用顶点表示活动, 用有向边< vi, vj >表示vi 必须先于 v j进行. 如果有有向环则说明某项活动以自 ...

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

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

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

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

最新文章

  1. 绕开数学,讲讲信息论
  2. 网络防嗅探工具SniffJoke
  3. 清华大学-美团数字生活联合研究院成立
  4. 互动直播的视频录制与合成—支持多人离线重入
  5. Activity内部Handler引起内存泄露的原因分析
  6. android 模仿 弹性菜单
  7. 34.Odoo产品分析 (四) – 工具板块(5) – 设备及联系人目录(1)
  8. 计算机辅助设计与制造实例教程答案,计算机辅助设计实例教程= Example Course of Computer Aided Design...
  9. WORD导出PDF生成书签
  10. 基于matlab进行图像处理学习——从入门到入魔
  11. MapGuide 添加临时点图层
  12. python词频统计GUI(thinter)
  13. C语言单链表 看不懂temp->next = book; book->next =NULL;
  14. 第33篇 Android Studio实现五子棋游戏(四)棋子类和主类
  15. 【代码】H5页面实现唤起AndroidAPP并传递参数
  16. jdbc入门到精通1.1访问数据库实战
  17. 在线报表设计实战系列 – ③制作交叉分析表
  18. 电视剧《大人物》40全集在线观看
  19. spring自动装配原理
  20. java:P1157 组合的输出

热门文章

  1. 第八周项目实践6 KMP算法(串的模式匹配)
  2. Reorder List
  3. BufferedReader和BufferedWriter读写文件
  4. ceil--朝正无穷大方向取整
  5. pyqt入门教程(一)
  6. mysql数据库有几种删除方式_sql有几种删除表数据的方式
  7. linux或者shell进入vi命令
  8. 七牛云图片存储---Java
  9. 转载:left join和left semi join的联系和区别
  10. Linux的硬盘分区