zoukankan      html  css  js  c++  java
  • 拓扑排序详解

    拓扑排序看起来很难,其实了解后不算难(思想非常清楚)

    关键掌握思想后需要学会应用到具体的题目中去。(从入度为0到出度为0)

    1、拓扑排序的介绍
    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。
        拓扑排序对应施工的流程图具有特别重要的作用,它可以决定哪些子工程必须要先执行,哪些子工程要在某些工程执行后才可以执行。为了形象地反映出整个工程中各个子工程(活动)之间的先后关系,可用一个有向图来表示,图中的顶点代表活动(子工程),图中的有向边代表活动的先后关系,即有向边的起点的活动是终点活动的前序活动,只有当起点活动完成之后,其终点活动才能进行。通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。
        一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行(对于数据流来说就是死循环)。在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
     
    2、拓扑排序的实现步骤
    在有向图中选一个没有前驱的顶点并且输出
    从图中删除该顶点和所有以它为尾的弧(白话就是:删除所有和它有关的边)
    重复上述两步,直至所有顶点输出,或者当前图中不存在无前驱的顶点为止,后者代表我们的有向图是有环的,因此,也可以通过拓扑排序来判断一个图是否有环。
     

    3、拓扑排序示例手动实现
    在一个有向图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。
    先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点指向的节点的入度减一。
    一直做改操作,直到所有的节点都被分离出来。
    如果最后不存在入度为0的节点,那就说明有环,不存在拓扑排序,也就是很多题目的无解的情况。
    下面是算法的演示过程。

    4.实现代码(队列):O(V+E)
        queue<int>q;
    
        vector<int>edge[n];//这里使用了数组的vector数组来表示连接关系,实际上结构体也可以完成此任务
    
        for(int i=0;i<n;i++)  //n  节点的总数
    
            if(in[i]==0) q.push(i);  //将入度为0的点入队列
    
        vector<int>ans;   //ans 为拓扑序列(其实队列也可以完成)
    
        while(!q.empty())
    
        {
    
            int p=q.front(); q.pop(); // 选一个入度为0的点,出队列
    
            ans.push_back(p);
    
            for(int i=0;i<edge[p].size();i++)
    
            {
    
                int y=edge[p][i];    //y表示的是点p的直接后继结点
    
                in[y]--;    //入度减1
    
                if(in[y]==0)    //入度为0的点则需要入队
    
                    q.push(y);  
    
            }
    
        }
    
        if(ans.size()==n)   
    
        {
    
            for(int i=0;i<ans.size();i++)
    
                printf( "%d ",ans[i] );
    
            printf("
    ");
    
        }
    
        else printf("No Answer!
    ");   //  ans 中的长度与n不相等,就说明无拓扑序列
            

    ————————————————
    参考来源:
    https://blog.csdn.net/qq_35644234/article/details/60578189
    https://blog.csdn.net/qq_41713256/article/details/80805338
  • 相关阅读:
    [Javascript] Closure Cove, 1
    [Backbone]7. Collection Views, Custom Events
    [Backbone]6. Collections.
    Immediately-Invoked Puzzler
    [Javascipt] Immediately-Invoker 2
    [Javascript] Using map() function instead of for loop
    [Javascript] Funciton Expression
    [Backbone]5. Model & View, toggle between Models and Views -- 2
    JS-jQuery-EasyUI:百科
    笔记-Java-Spring MVC:JAVA之常用的一些Spring MVC的路由写法以及参数传递方式
  • 原文地址:https://www.cnblogs.com/xwh-blogs/p/12596250.html
Copyright © 2011-2022 走看看