当前位置:   article > 正文

数据结构-图的遍历和应用(DAG、AOV、AOE网)_dag邻接矩阵

dag邻接矩阵

目录

*一、广度优先遍历(BFS)

广度优先生成树

广度优先生成森林

*二、深度优先遍历

深度优先生成树

深度优先生成森林

二、应用

2.1最小生成树

*Prim算法

*Kruskal算法

2.2最短路径

 *BFS算法

*Dijkstra算法

 *Floyd算法

*2.3有向无环图(DAG网)

 *2.4拓扑排序(AOV网)

*逆拓扑排序

 *2.5关键路径(AOE网)

*一、广度优先遍历(BFS)

类似树的广度遍历

 FirstNeighbor(G,x):求图G中顶点x的第一个邻接点,若有则返回顶点号,没有返回-1

NextNrighbor(G,x,y):假设图G中顶点y是顶点x的邻接点,返回除y之外顶点x的下一个邻接点的顶点号,若y就是最后一个返回-1

  1. bool visited[MAX_VERTEX_NUM];        //访问标记数组
  2. void BFS(Graph G,int v){
  3. visit(v); //访问初始顶点v
  4. visited[v]=TRUE; //对v做已访问标记
  5. Enqueue(Q,v); //入队列
  6. while(!isEmpty(Q)){
  7. Dequeue(Q,v); //顶点v出队
  8. for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){ //检测v所以邻接点
  9. if(!visited[w]){
  10. visit(w); //访问顶点w
  11. visited[w]=TRUE; //对w做已访问标记
  12. Enqueue(Q,w); //入队列
  13. }
  14. }
  15. }
  16. }
  1. void BFSraverse(Graph G){
  2. for(i=0;i<G.vexnum;++i)
  3. visired[i]=FASLE; //初始化标记数组
  4. InitQueue(Q); //初始化辅助队列
  5. for(i=0;i<G.vexnum;++i)
  6. if(!visited[i]) //对每个连通分量调用一次BFS
  7. BFS(G,i);
  8. }

空间复杂度:最坏。辅助队列O(V)

邻接矩阵时间复杂度:O(V2)

邻接表时间复杂度:O(V+E)

广度优先生成树

    邻接表生成不唯一,具体看数据先后顺序

广度优先生成森林

        一个连通分量一个树,多个(非连通图)就是森林

*二、深度优先遍历

类似树的先序遍历

  1. bool visited[MAX_VERTEX_NUM]; //访问标记数组
  2. void DFS(Graph G,int v){
  3. visit(v); //访问v
  4. visited[v]=TRUE; //标记已访问
  5. for(w=FirstNeighbor(G,V);w>=0;w=NextNeighor(G,v,w)) //邻接顶点
  6. if(!visited[w]){
  7. DFS(G,w);
  8. }
  9. }
  1. void DFSraverse(Graph G){
  2. for(v=0;v<G.vwxnum;++v)
  3. visited[v]=FALSE;
  4. for(v=0;v<G.vexnum;++v)
  5. if(!visited[v])
  6. DFS(G,v);
  7. }

空间复杂度:最后O(1)  ,最坏情况:O(V)

邻接矩阵时间复杂度:O(V2)

邻接表时间复杂度:O(V+E)

邻接表存储顺序性不一致,遍历序列不一样

深度优先生成树

    邻接表生成不唯一,具体看数据先后顺序

深度优先生成森林

        一个连通分量一个树,多个(非连通图)就是森林

二、应用

2.1最小生成树

*Prim算法

从某一个顶点开始构建生成树;每一次将代价最小的新顶点纳入生成树,直到所有顶点都纳入为止

时间复杂度O(V2)    适用于边稠密图

*Kruskal算法

每次选择一条权值最小边,使这条边两头连通(已经连通不用),直到所有结点连通

时间复杂度O(elog2e)  适合用于边稀疏图

2.2最短路径

 *BFS算法

*Dijkstra算法

 *Floyd算法

  动态规划思想

 

 每轮看A1[i][j]>A1[i][n]+A1[n][j] ,n为第几轮,n也就是几个顶点为中转点

A(2)=AA(1)A(0)A(1)A(2)
V0V1V2V0V1V2V0V1V2V0V1V2
V00613061306100610
V1100410041004904
V250511551105110

 中转点为第几轮换的就是几

path(2)=V0V1V2
V0-1-11
V12-1-1
V2-10-1

 第一轮(A(0)):A1[i][j]>A1[i][0]+A1[0][j],更新值

 第二轮(A(1)):A1[i][j]>A1[i][1]+A1[1][j]

 第三轮(A(2)):A1[i][j]>A1[i][2]+A1[2][j]

几个顶点几轮

根据上面A(2)可知V1V2最短路径为4,根据path(2)为-1没有中转,路径为V1>V2

根据上面A(2)可知V0V2最短路径为10, 根据path(2)为1,经过V1顶点中转,路径为V0>V1>V2

  1. for(int k=0;k<n;lk++){ //考虑vk为中转点
  2. for(int i=0;i<n;i++){ //遍历矩阵,i行,j列
  3. for(int j=0;j<n;j++){
  4. if(A[i][j]>A[i][k]+A[k][j]){ //以vk为中转点的路径更短
  5. A[i][j]=A[i][k]+A[k][j]; //最短路径
  6. path[i][j]=k; //中转点
  7. }
  8. }
  9. }
  10. }

 时间复杂度:O(V3)

空间复杂度:O(V2)

*2.3有向无环图(DAG网)

        若一个有向图中不存在环,则称为有向无环图,简称DAG图

 有向无环图是描述含有公共子式的表达式的有效工具,列如表达式((a+b)(b(c+d))+(c+d)e)((c+d)e)

 DAG不可能出现重复操作数

 *2.4拓扑排序(AOV网)

AOV网:若用DAG图表示一个工程图,其顶点表示活动,用边表示活动Vi必选先于活动Vj进行的这样一种关系,则这种有向图称顶点表示活动的网络,记为AOV网。ViVj的直接前驱,VjVi直接后继,不能自己做自己的前驱和后继。每个工程只出现一次

 

 时间复杂度:O(V+E)

若采用邻接矩阵则O(V2)

*逆拓扑排序

 *2.5关键路径(AOE网)

        在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的        开销(如时间),称之为用边表示活动的网络,简称AOE网

源点:AOE网仅有一个入度未0的顶点,称为开始顶点(源点),表示工程的开始。

汇点:也仅有一个出度为0的顶点,称结束顶点(汇点),表示工程的结束

关键路径:从源点到汇点路径可能有多条,所有路径中,路径出度最大的为关键路径

事件(顶点)vk最早发生时间ve(k):决定了所有从vk开始的活动能够开工的最早时间

活动(边)ai的最早开始时间e(i):指该活动弧的起点所表示事件的最早发生时间

事件vk的最迟发生时间vl(k):指不推迟整个工程前提下,事件最迟必选发生的时间e(i)=ve(k)

 活动(边)ai的最迟开始时间l(i):指活动弧的终点所表示事件的最迟发生时间与该活动所需时间之差。l(i)=vl(i)Weight(vk,vj) 

时间余量:d(i)=l(i)e(i)

 关键活动、关键路径的特性

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/690311
推荐阅读
相关标签
  

闽ICP备14008679号