• 【考研】数据结构考点——拓扑排序


    前言 

    本文内容源于对《数据结构(C语言版)》(第2版)和王道讲解及博主的笔记整理和总结。

    可结合以下链接“食用”:

    【考研】《数据结构》知识点总结.pdf_数据结构知识点总结pdf,考研数据结构知识点总结背诵-其它文档类资源-CSDN下载

    一、基本概念

    1、拓扑排序:可以用来判断图是否有环。(以下存储结构:邻接表)(网:带权的图)

    2、有向无环图(DAG图):一个无环的有向图。(描述一项工程或系统的进行过程的有效工具)

    3、AOV-网:用顶点表示活动,用弧表示活动间的优先关系的有向图。

    4、拓扑排序:AOV-网中所有顶点排成一个线性序列,该序列满足:若在AOV-网中由顶点  到顶点  有一条路径,则在该线性序列中的顶点  必定在顶点  之前

    5、对于一般的图来说,若其邻接矩阵是三角矩阵,则存在拓扑序列,反之不一定成立。

    6、若一个有向图的顶点不能排在一个拓扑序列中,表示图中必有回路,该回路构成一个强连通分量,即则可判定该有向图含有顶点数目大于1的强连通分量

    7、若拓扑排序算法中为暂存入度为0的顶点,可使用栈,也可使用队列。

    二、拓扑排序的过程

    (1)在有向图中选一个无前驱的顶点且输出它。

    (2)从图中删除该顶点和所有以它为尾的弧。

    (3)重复(1)和(2),直至不存在无前驱的顶点。

    (4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在环,否则输出的顶点序列即为一个拓扑序列。

    三、拓扑排序的实现

    引入以下辅助的数据结构:

    (1) 一维数组indegree[i]:存放各顶点入度,没有前驱的顶点就是入度为零的顶点。删除顶点及以它为尾的弧的操作,可不必真正对图的存储结构进行改变,可用弧头顶点的入度减1的办法来实现。
    (2) 栈S:暂存所有入度为零的顶点,这样可以避免重复扫描数组indegree检测入度为0的顶点,提高算法的效率。
    (3) 一维数组topo[i]:记录拓扑序列的顶点序号。

    【算法步骤】
    ① 求出各顶点的人度存人数组 indegree[i] 中,并将入度为0的顶点入栈。
    ② 只要栈不空,则重复以下操作:
    ● 将栈顶顶点 V 出栈并保存在拓扑序列数组 topo 中; 
    ● 对顶点 v_i 的每个邻接点 v_k 的入度减1,如果 v_k 的入度变为0,则将 v_k 入栈。
    ③ 如果输出顶点个数少于AOV-网的顶点个数,则网中存在有向环无法进行拓扑排序,否
    则拓扑排序成功。

    1. //【算法描述】
    2. Status Topologica lSort (ALGraph G,int topo[] ){
    3. // 有向图 G 采用邻接表存储结构
    4. // 若 G 无回路,则生成 G 的一个拓扑序列 topo[] 并返回 OK, 否则 ERROR
    5. FindInDegree (G, indegree); //求出各顶点的入度存人数组indegree中
    6. InitStack(S); //栈 s 初始化为空
    7. for (i = 0; i < G.vexnum; ++i)
    8. if(!indegree[i])
    9. Push(S, i); //入度为0者进栈
    10. m = 0; //对输出顶点计数,初始为0
    11. while (!StackEmpty(S)){ //栈 s 非空
    12. Pop(S, i); //将栈顶顶点v(i)出栈
    13. topo[m] = i; //将v(i)保存在拓扑序列数组 topo 中
    14. ++m; //对输出顶点计数
    15. p = G.vertices[i].firstarc; //p 指向 v(i) 的第一个邻接点
    16. while(p != NULL){
    17. k = p->adjvex; // v(k) 为 v(i) 的邻接点
    18. --indegree[k]; // v(i) 的每个邻接点的入度减1
    19. if(indegree[k] == 0) Push(S, k); //若入度减为0,则入栈
    20. p = p->nextarc; //p 指向顶点 v(i) 下一个邻接结点
    21. }
    22. }
    23. if (m < G.vexnum) //该有向图有回路
    24. return ERROR;
    25. else return OK;
    26. }

     【算法分析】

    对有 n 个顶点和 e 条边的有向图而言,

    建立求各顶点入度的时间复杂度为 O(e) ;

    建立零入度顶点栈的时间复杂度为 O(n)

    在拓扑排序过程中,若有向图无环,则每个顶点进栈,出一次栈,入度减1的操作在循环中总共执行 e 次,所以,总的时间复杂度为 O(n +e) 。
     

  • 相关阅读:
    人脸识别:insightface自定义数据集制作 | 附练手数据集
    数据结构刷题——栈(上)
    AlexNet论文解读
    leetcode - 725. Split Linked List in Parts
    mybatis防注入
    ME1W隐式增强 增加字段学习
    html使用天地图写一个地图列表
    手电筒UL1576测试报告申请流程亚马逊审核
    【洛谷 P1518】[USACO2.4] 两只塔姆沃斯牛 The Tamworth Two 题解(模拟+循环)
    JVM运行时数据区——程序计数器
  • 原文地址:https://blog.csdn.net/qq_34438969/article/details/126082031