数据结构第三遍补充(图的应用)

这篇具有很好参考价值的文章主要介绍了数据结构第三遍补充(图的应用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. Kruskal算法

  1. Kruskal算法实现的关键是:当一条边加入到TE的集合后,如何判断是否构成回路?
    答: 简单的解决方法是:定义一个一维数组Vset[n]; 存放图T中每个顶点所在的连通分量的编号。
    ① 初值: Vset[i]=i, 表示每个顶点各自组成一个连通分量,连通分量的编号简单地使用顶点在图中的位置(编号)。
    ② 当往T中增加一条边(Vi, Vj) 时,先检查Vset[i]和Vset[j]值:
    a 若Vset[i]=Vset[j]: 表明vi和vj处在同一个连通分量中,加入此边会形成回路;
    b 若Vset[i]≠Vset[j]:则加入此边不会形成回路,将此边加入到生成树的边集中。
    ③加入一条新边后, 将两个不同的连通分量合并,将一个连通分量的编号换成另一个连通分量的编号。

算法实现

MSTEdge *Kruskal MST(ELGraph *G)
/*用Kruskal算法构造图G的最小生成树*/
{  MSTEdge TE[ ;
   int  j, k, V, s1, s2, Vset[] ;
  WeightType w ;
  Vset=(int *)malloc(G->vexnum *sizeof(int)) ;
  for (=0; j<G->vexnum; j++)
     Vset[j]=j ; /* 初始化数组Vset[n] */
     sort(G->edgelist); /* 对表按权值从小到大排序*/
   j=0 ;k=0;
   while (k<G->vexnum-1 &&j< G->edgenum)
     { s1=Vset[G->edgelist[j].vex1];
       s2= Vset[G->edgelist[j].vex2] ;
     /*若边的两个顶点的连通分量编号不同,边加入到TE中*/
      if (s1!=s2)
       { TE[k].vex 1=G->edgelist[j].vex1 ;
         TE[k].vex2=G->edgelist[j].vex2 ;
         TE[k].weight=G->edgelis t[j].weight;
        for (v=0; v<G->vexnum; v++)
            if (Vset[v]= =s2) Vset[v]=s1 ;
      }
     j++ ;
   }
   free(Vset) ;
  return(TE) ;}
/*求最小生成树的Kruskal算法*/
  1. 算法分析:
    设带权连通图有n个顶点,e条边,则算法的主要执行是:
    ① Vset数组初始化: 时间复杂度是O(n) ;
    ② 边表按权值排序: 若采用堆排序或快速排序,时间复杂度是O(eloge) ;
    ③ while循环:最大执行频度是O(n),其中包含修改Vset数组,共执行n-1次,时间复杂度是0(n2) ;
    整个算法的时间复杂度是O(eloge+n2)。

二.拓扑排序

  1. 定义
    (1)拓扑排序(Topological Sort) : 由某个集合上的一个偏序得到该集合上的一个全序的操作。
    ① 集合上的关系:集合A上的关系是从A到A的关系(AxA)
    ② 关系的自反性:若Va∈A有(a, a)∈R,称集合A上的关系R是自反的。
    ③关系的对称性:如果对于a, b∈A,只要有(a,b)∈R就有(b, a)∈R ,称集合A上的关系R是对称的
    ④ 关系的对称性与反对称性:如果对于a, b∈A ,只要有(a, b)∈R就有(b, a)∈R ,称集合A上的关系R
    是对称的。如果对于a, b∈A,仅当a=b时有(a,b)∈R和(b, a)∈R ,称集合A上的关系R是反对称的。
    ⑤关系的传递性:若a, b, c∈A,若(a, b)∈R, 并且(b, c)∈R, 则(a, c)∈R ,称集合A上的关系R是传递的。
    ⑥ 偏序:若集合A上的关系R是自反的,反对称的和传递的,则称R是集合A上的偏序关系。
    ⑦ 全序:设R是集合A上的偏序关系,Va, b∈A,必有aRb或bRa,称R是集合A上的全序关系。
    即偏序是指集合中仅有部分元素之间可以比较,而全序是指集合中任意两个元素之间都可以比较。
  2. 在AOV网中,若有有向边<i,j>,则i是j的直接前驱,j是的直接后继;推而广之,若从顶点i到顶点j有 有向路径,则i是j的前驱,j是i的后继。
  3. 在AOV网中,不能有环,否则,某项活动能否进行是以自身的完成作为前提条件。
    检查方法:对有向图的顶点进行拓扑排序,若所有顶点都在其拓扑有序序列中,则无环。
  4. 向图的拓扑排序:构造AOV 网中顶点的一个拓扑线性序列(v’1,V’2, …,v’n),使得该线性序列不仅保持有向图中顶点之间的优先关系,而且对原图中没有优先关系的顶点之间也建立-种(人为的)优先关系。
  5. 手工实现
    如图是一个有向图的拓扑排序过程,其拓扑序
    列是: (V1,V6,V4,V3;V2,Vs)
    数据结构第三遍补充(图的应用)
  6. 算法思想
    ◆ 采用 正邻接链作为AOV网的存储结构;
    ◆ 设立堆栈,用来暂存入度为0的顶点;
    ◆ 删除顶点以它为尾的弧:弧头顶点的入度减1。
  7. 算法实现
    (1)统计各顶点入度的函数
void count indegree(ALGraph *G)
{ int k ; 
  LinkNode *p ;
  for (k=0; k<G->vexnum; k++)
     G-> adjlist[kJ.indegree=0; /*顶点入度初始化*/
  for (k=0; k<G->vexnum; k++)
   { p=G-> adjlist[k].firstarc ;
      while (p!=NULL)/*顶点入度统计*/
      { G->adjlist[p->adjvex].indegree++ ;
         p=p-> nextarc ;
      }
   }
 }

(2)拓扑排序算法

int Topologic Sort(ALGraph *G, int topol[)
/*顶点的拓扑序列保存在一维数组topol中 */
{  int k, no, vex_ no, top=0, count =0,boolean=1 ;
   int stack[MAX_ VEX] ;  /*用作堆栈*/
   LinkNode *p ; 
   count_ indegree(G); /* 统计各顶点的入度*/
   for (k=0; k<G->vexnum; k++)
     if (G->adjJist[k].indegree--0)
          stack[+ +top]=G-> adjlist[k].data ;
    do{if(top==0) boolean=0 ;
    else
     { no=stack[top-] ;/*栈顶元素出栈*/
       topl[++count]=no; /* 记录顶点序列*/
        p=G-> adjlist[no].firstarc ;
       while (p!=NULL) /* 删除以顶点为尾的弧*/
         { vex_ no=p->adjvex ;
           G-> adjlist[vex no]indegree--;
           if (G->adjlist[vex no].indegree==0)
              stack[++top]=vex_ no ;
        p=p-> nextarc ;
         }
     }
  }while(boolean==0) ;
if (count<G->vexnum) return(-1) ;
else return(1);
}
  1. 算法分析:
    设AOV网有n个顶点,e条边,则算法的主要执行是:
    ◆统计各顶点的入度: 时间复杂度是O(n+e) ;
    ◆入度为0的顶点入栈:时间复杂度是O(n) ;
    ◆排序过程:顶点入栈和出栈操作执行n次,入度减1的操作共执行e次,时间复杂度是O(n+e) ;因此,整个算法的时间复杂度是O(n+e)。

三.关键路径

  1. 算法思想
    ①利用拓扑排序求出AOE网的一个拓扑序列;
    ②从拓扑排序的序列的第一个顶点(源点)开始,按拓扑顺序依次计算每个事件的最早发生时间ve(i) ;
    ③从拓扑排序的序列的最后一个顶点(汇点)开始,按逆拓扑顺序依次计算每个事件的最晚发生时间vl(i) ;
    对于图7-24的AOE网,处理过程如下:拓扑排序的序列是:(Vo, V1, V2, V3,V4, V5, V6,V7,V8)
  2. 算法实现
void critical path(ALGraph *G)
{ int j,k,m; LinkNode *p ;
   if (Topologic_Sort(G)==-1)
       printf(“\nAOE网中存在回路,错误!!\n\n”) ;
   else
    { for( j=0; j<G->vexnum; j++)
           ve[j]=0 ;/*事件最早发生时间初始化*/
      for (m=0; m<G->vexnum; m++)
      { j=topol[m] ;
        p=G-> adjlist[j].firstarc ;
        for(; p!=NULL; p=p->nextarc )
        { k=p->adjvex ;
          if (ve[j]+p->weight>ve[k) 
              ve[k]=vel[jl+p->weight;
        }
      } /*计算每个事件的最早发生时间ve值*/
      for ( j=0; j<G->vexnum; j++) 
           vI[j]=ve[j] ; /* 事件最晚发生时间初始化*/
     for (m=G->vexnum-1; m>=0; m--)
          { j=topol[m] ; p=G->adjlistijJ.firstarc;
             for (; p!=NULL; p=p->nextarc )
              { k=p->adjvex ;
                if (vI[k]-p->weight<vI[j)
                  vI[i]=vl[k]-p->weight ;
              }
           } /*计算每个事件的最晚发生时间vI值*/
   for (m=0; m<G->vexnum; m++)
      { p=G->adjlist[m].firstarc ;
        for (; p!=NULL; p=p->nextarc )
          { k=p->adjvex ;
            if ( (ve[m]+p->weight=VI[k])
                 printf(<%d, %d>, m,j"); 
          }
      }/*输出所有的关键活动*/
    }/* end ofelse */
   }

  1. 算法分析
    设AOE网有n个事件,e个活动,则算法的主要执行是:
    ◆进行拓扑排序:时间复杂度是O(n+e) ;
    ◆求每个事件的ve值和vI值:时间复杂度是O(n+e) ;
    ◆根据ve值和vI值找关键活动:时间复杂度是O(n+e) ;因此,整个算法的时间复杂度是0(n+e)。

四 习题

(1)分析并回答下列问题:
①图中顶点的度之和与边数之和的关系?
②有向图中顶点的入度之和与出度之和的关系?
③具有n个顶点的无向图,至少应有多少条边才能确保是一个连通图?若采用邻接矩阵表示,则该矩阵的大小是多少?
④具有n个顶点的有向图,至少应有多少条孤才能确保是强连通图的?为什么?

(2) 设有向图G=(V,E), 其中V= {a,b,c,d,e}, E={<a,b>, <a,d>, <b,a>, <c,b>, <c,d>, <d,e>,<e,a>, <e,b>,<e,c>}
①请画出该有向图,并求各顶点的入度和出度。
②分别画出有向图的正邻接链表和逆邻接链表。

(3)对图7-27所示的带权无向图。、
①写出相应的邻接矩阵表示。
②写出相应的边表表示。
③求出各顶点的度。

(4)已知有向图的逆邻接链表如图7-28所示。
①画出该有向图。
②写出相应的邻接矩阵表示。
③写出从顶点a开始的深度优先和广度优先遍历序列。
④画出从顶点a开始的深度优先和广度优先生成树

(5)一个带权连通图的最小生成树是否唯一?在什么情况下可能不唯一?

(6)对于图7-27所示的带权无向图。
①按照Prime算法给出从项点2开始构造最小生成树的过程。
②按照Kruskal算法给出最小生成树的过程。

(7)已知带权有向图如图7-29所示,请利用Dijkstra算法从顶点V.出发到其余顶点的最短路径及长度,给出相应的求解步骤。

(8)已知带权有向图如图7-30所示,请利用Floyd算法求出每对顶点之间的最短路径及路径长度。

(9)一个AOV网用邻接矩阵表示,如图7-31。 用拓扑排序求该A0V网的一个拓扑序列,给出相应的步骤。

(10)拓扑排序的结果不是唯一的,请给出如图7-32所示的有向图的所有可能的拓扑序列。

(11)请在深度优先搜索算法的基础上设计一个对有向无环图进行拓扑排序的算法。

(12)设计一个算法利用图的遍历方法输出一个无向图G中从顶点V:到V的长度为S的简单路径,设图采用邻接链表作为存储结构。

(13)假设一个工程的进度计划用AOE网表示,如图7-33所示。
①求出每个事件的最早发生时间和最晚发生时间。
②该工程完工至少需要多少时间?
③求出所有关键路径和关键活动。
数据结构第三遍补充(图的应用)

数据结构第三遍补充(图的应用)文章来源地址https://www.toymoban.com/news/detail-461694.html

到了这里,关于数据结构第三遍补充(图的应用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构-图的遍历和应用(DAG、AOV、AOE网)

    目录 *一、广度优先遍历(BFS) 广度优先生成树 广度优先生成森林 *二、深度优先遍历 深度优先生成树 深度优先生成森林 二、应用 2.1最小生成树 *Prim算法 *Kruskal算法 2.2最短路径  *BFS算法 *Dijkstra算法  *Floyd算法 *2.3有向无环图(DAG网)  *2.4拓扑排序(AOV网) *逆拓扑排序  *2.5关键路

    2024年02月10日
    浏览(28)
  • 数据结构第三次实验-图及其应用

    一、实验目的 掌握图的存储、构建、搜索等操作和应用,能用最短路径及其搜索等算法编制较 综合性的程序,求解最优路线问题,进行程序设计、数据结构和算法设计等方面的综合训练。 二、实验内容及要求 1、任务描述 实验内容: 用户驾车出行由于出行目的的不同对道

    2024年02月06日
    浏览(28)
  • 【数据结构】图的应用:最小生成树;最短路径;有向无环图描述表达式;拓扑排序;逆拓扑排序;关键路径

    目录 1、最小生成树 1.1 概念  1.2 普利姆算法(Prim) 1.3 克鲁斯卡尔算法(Kruskal)  2、最短路径 2.1 迪杰斯特拉算法(Dijkstra) 2.2 弗洛伊德算法(Floyd)  2.3 BFS算法,Dijkstra算法,Floyd算法的对比 3、有向无环图描述表达式 3.1 有向无环图定义及特点 3.2 描述表达式 4、拓扑排序

    2024年02月07日
    浏览(33)
  • 数据结构--图的存储结构

    第九话  数据结构之图的存储 文章目录 一、了解什么是图 二、图的定义和基本术语 三、存储结构之邻接矩阵 1.邻接矩阵的介绍 2.邻接矩阵的创建 3.主函数中实现 四、存储结构之邻接表 1.邻接表的介绍 2.邻接表的创建 3.在主函数中实现 五、总结 一切尽在图结构 图的应用非

    2024年02月07日
    浏览(40)
  • 数据结构—图的存储结构

    回顾:数据的逻辑结构 集合——数据元素间除 “同属于一个集合” 外,无其他关系。 线性结构——一个对一个,如线性表、栈、队列 树形结构——一个对多个,如树 图形结构——多个对多个,如图 6.1图的定义和术语 无向图 :每条边都是 无 方向的; 有向图 :每条边都是

    2024年02月14日
    浏览(28)
  • 16-数据结构-图的存储结构

    简介:主要为图的顺序存储和链式存储。其中顺序存储即邻接矩阵的画法以及代码,邻接矩阵又分为有权图和无权图,区别就是有数据的地方填权值,无数据的地方可以填0或者∞,而有权图和无权图,又细分为有向图和无向图。无向图为对称矩阵,因为没有方向可言,出度入

    2024年02月09日
    浏览(26)
  • 数据结构——图的基本定义以及图的存储结构,邻接矩阵,邻接表

    目录 图的定义和术语 图的存储结构 顺序存储结构—邻接矩阵 链式存储结构 邻接表 邻接多重表 十字链表 图的遍历 图的连通性问题 有向无环图及其应用 最短路径 图的定义:图是一种非线性的复杂的数据结构,图中的数据元素的关系是多对多的关系 ,在图中我们常常把数

    2024年02月04日
    浏览(40)
  • 【数据结构(28)】6.4 图的存储结构

    由于图的结构比较复杂,任意连个顶点之间都可能存在联系,因此无法以数据元素在存储区中的物理位置来表示元素之间的关系,即 图没有顺序存储结构 ,但是可以借助二维数组来表示元素之间的关系,即 邻接矩阵表示法 。 另一方面,由于图的任意两个顶点减都可能存在

    2024年02月03日
    浏览(31)
  • 数据结构--5.0.1图的存储结构

    目录 一、邻接矩阵(无向图)  二、邻接矩阵(有向图) 三、邻接矩阵(网) 四、邻接表(无向图) 五、邻接表(有向图)   ——图的存储结构相比较线性表与树来说就复杂很多 ——对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放。         树结构

    2024年02月10日
    浏览(34)
  • 数据结构 | 图的遍历

    使用邻接矩阵法存储图的信息,其中 一维矩阵 Vexs[] 存储节点信息 二维矩阵 Edges[][] 存储边的信息 一维矩阵 visited[] 记录当前节点是否被访问过,用于后面的遍历 本文所使用的图的结构如下: 对应的 Vexs[] 为:A,B,C,D,E,F(对应的数组下标从0到5) 对应的 Edges[][] 如下: 图的

    2024年02月04日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包