美文网首页
拓扑排序

拓扑排序

作者: 执怿 | 来源:发表于2023-04-14 22:34 被阅读0次

    拓扑排序

    一个顶点活动网(AOV网)是一个有向无环图

    正常情况下,通过拓扑排序,按照拓扑序列(不是唯一的)进行执行,所有的活动都能够被完成

    但是,如果图中有环,则有一部分活动不能被正常完成(相当于形成了一个循环依赖,没有一个点的入读能够变为0,那这些点对应的活动都不能被执行)

    图可以通过邻接表进行存储

    img

    解决拓扑排序问题使用到的数据结构稍有不同

    Vertex{

    Int 入度;

    char 数据

    Edge 第一条出边
    }

    Edge{

    //Int weight权重

    Vertex 指向的顶点

    Edge 下一条出边

    }

    构造这样的数据:

    1. 首先有n个有编号的有序事件,为每个事件创建一个Vertex,data数据域存放编号,将这些Vertex 按序 存放到List<Vertex>中
    2. 遍历依赖关系,根据每个依赖关系建立Edge 如任务2依赖任务1和任务0:则建立两条边,分别指向Vertex0和Vertex1,第一条边的Edge为第二条边,第二条边的Edge为null,在这个过程中,要同时更新指向的Vertex的入度;然后将Vertex2的Edge指向第一条边

    得到一个List<Vertex>,其中包含了顶点信息和边的信息

    下面通过这个数据进行处理:

    • Int outputVertices=0;记录输出的顶点的个数,如果最终输出的顶点的个数和List的长度相同,也就是输出了所有的顶点,完成了所有的任务,则这个图是正常的AOV,是没有环的
    • Stack<Vertex> stack=new Stack<>();

    将所有入读为0的顶点入栈,这些任务是现在可以进行输出的(也就是可以完成的,因为它们的前置任务都已经完成了)

    • for (Vertex vertex : graph) { if (vertex. inNumber O) { stack. push (vertex);
    • 每次拿出一个顶点,要对该顶点的所有出边进行处理,如果处理过程中有新的入读为0的顶点要进行压栈

    循环,直到栈为空,此时没有可以完成的任务

    • 判断
    • if true. (outvertices graph.size()){ return true;
    在顶点不需要存储具体的数据、边不存在权重的情况下,可以使用更加简单的数据结构

    两个数组就可以解决:

    深入理解拓扑排序(Topological sort) - 简书 (jianshu.com)

    关于上面的截图中二维数组的使用:

    image-20230415155210515

    这样是可以的,或者用arrayList,只要构造成一种二维表的形式就可以

    相关文章

      网友评论

          本文标题:拓扑排序

          本文链接:https://www.haomeiwen.com/subject/ucitjdtx.html