收藏 分享(赏)

数据结构.第7章.图.2.图的遍历和连通性.pptx

上传人:hskm5268 文档编号:7011039 上传时间:2019-04-30 格式:PPTX 页数:46 大小:2.27MB
下载 相关 举报
数据结构.第7章.图.2.图的遍历和连通性.pptx_第1页
第1页 / 共46页
数据结构.第7章.图.2.图的遍历和连通性.pptx_第2页
第2页 / 共46页
数据结构.第7章.图.2.图的遍历和连通性.pptx_第3页
第3页 / 共46页
数据结构.第7章.图.2.图的遍历和连通性.pptx_第4页
第4页 / 共46页
数据结构.第7章.图.2.图的遍历和连通性.pptx_第5页
第5页 / 共46页
点击查看更多>>
资源描述

1、数据结构 Data Structures,张 凯 计算机学院 软件工程系,2011年3月12日,图的连通性问题,第7章 图,图的定义和术语,图的存储结构,图的遍历,有向无环图及其应用,最短路径,基本术语,7.3 图的遍历,从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。这一过程就叫做图的遍历。图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。通常有两条遍历图的路径 深度优先搜索 广度优先搜索,基本术语,7.3 图的遍历,基本术语,7.3 图的遍历,遍历实质:找每个顶点的邻接点的过程。 图的特点:图中可能存在回路,且图的任一顶点都可能与其它 顶点相通,在访问完某

2、个顶点之后可能会沿着某些 边又回到了曾经访问过的顶点。,解决思路:可设置一个辅助数组 visited n,用来标记每个被访 问过的顶点。它的初始状态为0,在图的遍历过程 中,一旦某一个顶点i 被访问,就立即改 visited i 为1,防止它被多次访问。,深度优先搜索(DFS),7.3 图的遍历,基本思想:从图中某顶点V0出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点;重复上述过程,直至图中所有顶点都被访问到为止。,Depth_First Search

3、,深度优先搜索(DFS),7.3 图的遍历,顶点访问序列为:v1, v2, v4, v8, v5, v3, v6, v7,v1,v6,v2,v5,v3,v8,v4,v7,从顶点v1出发,深度优先搜索(DFS),7.3 图的遍历,从顶点v2出发,v1,v6,v2,v5,v3,v4,顶点访问序列为:v2, v1, v3, v5, v4, v6,深度优先搜索(DFS),7.3 图的遍历,简单归纳: (1)访问起始点 v; (2)若v的第1个邻接点没访问过,深度遍历此邻接点; (3)若当前邻接点已访问过,再找v的第2个邻接点深度遍历。,深度优先搜索(DFS),7.3 图的遍历,(1)在访问图中某一起始

4、顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1; (2)再从 w1 出发,访问与 w1邻接但还未被访问过的顶点 w2; (3)然后再从 w2 出发,进行类似的访问, (4)如此进行下去,直至到达所有的邻接顶点都被访问过为止。 (5)接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。,讨论1:计算机如何实现DFS?,DFS 结果,邻接矩阵 A,辅助数组 visited n,起点,v2v1v3v5v4v6,开辅助数组

5、visited n!,v1,v6,v2,v5,v3,v4,0,0,0,0,0,0,1,1,1,1,1,1,讨论2:计算机如何实现DFS?,DFS 结果,邻接表,辅助数组 visited n,v1v2v4v8v5v3v6v7,开辅助数组 visited n!,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,v1,v6,v2,v5,v3,v8,v4,v7,起点,注意:在邻接表中,并非每个链表元素(表结点)都被扫描到,遍历速度很快。,图的深度优先遍历算法,7.3 图的遍历,Boolean visited MAX; / 访问标志数组Void DFSTraverse( Graph G,

6、Status (*Visit) (int v) / 对图G做深度优先遍历for (v=0; vG.vexnum; +v) visitedv = FALSE; / 访问标志数组初始化for (v=0; vG.vexnum; +v) if (!visitedv) DFS(G,v); / 对尚未访问的顶点调用DFS,图的深度优先遍历算法,7.3 图的遍历,void DFS (Graph G,int v) /从第v个顶点出发递归地深度优先遍历图Gvisitedv=TRUE ; Visit(v); /访问第v个顶点 for(w=FirstAdjVex(G,v); w=0; w=NextAdjVex(G,

7、v,w)if (!visitedw) DFS(G,w); /对v的尚未访问的邻接顶点w递归调用DFS ,DFS 算法效率分析,7.3 图的遍历,(设图中有 n 个顶点,e 条边) 如果用邻接矩阵来表示图,遍历图中每一个顶点都要从头扫描该顶点所在行,因此遍历全部顶点所需的时间为O(n2)。 如果用邻接表来表示图,虽然有 2e 个表结点,但只需扫描 e 个结点即可完成遍历,加上访问 n 个头结点的时间,因此遍历图的时间复杂度为O(n+e)。,DFS的非递归算法,7.3 图的遍历,从顶点vi出发进行DFS的递归过程也可以写成非递归的形式,此时需借助一个堆栈保存被访问过的结点,以便回溯时查找已被访问结

8、点的未被访问过的邻接点。,邻接表,辅助数组 visited n,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,v1,v6,v2,v5,v3,v8,v4,v7,起点,v1,v2,v4,v8,v5,v3,v6,v7,Stack,广度优先搜索(BFS),7.3 图的遍历,基本思想:从图中某个顶点V0出发,并在访问此顶点后依次访问V0的所有未被访问过的邻接点,之后按这些顶点被访问的先后次序依次访问它们的邻接点,直至图中所有和V0有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点;重复上述过程,直至图中所有顶点都被访问到为止。,Breadth

9、_First Search,广度优先搜索(BFS),7.3 图的遍历,顶点访问序列为:v1, v2, v3, v4, v5, v6, v7, v8,v1,v6,v2,v5,v3,v8,v4,v7,从顶点v1出发,广度优先搜索(BFS),7.3 图的遍历,v3,v5,v2,v9,v1,v6,从顶点v3出发,顶点访问序列为:v3, v2, v1, v6, v4, v5, v9, v8, v7,v4,v7,v8,v3,v5,v2,v9,v1,v6,v4,v7,v8,广度优先搜索(BFS),7.3 图的遍历,简单归纳 (1)在访问了起始点v之后,依次访问 v 的邻接点; (2)然后再依次访问这些顶点中

10、未被访问过的邻接点; (3)直到所有顶点都被访问过为止。,广度优先搜索(BFS),7.3 图的遍历,注意:广度优先搜索是一种分层的搜索过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有回退的情况。因此,广度优先搜索不是一个递归的过程,其算法也不是递归的。,讨论1:计算机如何实现BFS?,邻接表,除辅助数组visitedn外,还需再开一辅助队列!,起点,辅助队列,Q.rear,Q.front,V2,V1,V5,V3,V4,V6,辅助数组 visitedn,0,0,0,0,0,0,1,1,1,1,1,1,Q.rear,Q.front,Q.rear,Q.front,Q.rear,Q.fron

11、t,Q.rear,Q.front,Q.rear,Q.front,Q.rear,Q.front,广度优先搜索(BFS)非递归算法,void BFSTraverse(Graph G, Status (*Visit)(int v)/使用辅助队列Q和访问标志数组visitedv for (v=0; v=0;w=NextAdjVex(G,u,w))if ( ! visitedw) /w为u的尚未访问的邻接顶点visitedw = TRUE; Visit(w);EnQueue(Q, w); /if /whileif / BFSTraverse,BFS 算法效率分析,7.3 图的遍历,(设图中有 n 个顶点

12、,e 条边),如果使用邻接表来表示图,则BFS循环的总时间代价为 d0 + d1 + + dn-1 = O(e),其中的 di 是顶点 i 的度 如果使用邻接矩阵,则BFS对于每一个被访问到的顶点,都要循环检测矩阵中的整整一行( n 个元素),总的时间代价为O(n2)。,DFS与BFS之比较,7.3 图的遍历,空间复杂度相同,都是O(n)(借用了堆栈或队列) 时间复杂度只与存储结构(邻接矩阵或邻接表)有关,而与搜索路径无关。,图的连通性问题,7.4 图的连通性问题,1)无向图的连通分量和生成树 2)最小生成树 3)普里姆算法 4)克鲁斯卡尔算法,无向图的连通分量和生成树,7.4 图的连通性问题

13、,连通分量的顶点集:即从该连通分量的某一顶点出发进行搜索所得到的顶点访问序列; 生成树:某连通分量的极小连通子图; 生成森林:非连通图的各个连通分量的极小连通子图构成的集合。,无向图的连通分量和生成树,7.4 图的连通性问题,连通分量的顶点集:即从该连通分量的某一顶点出发进行搜索所得到的顶点访问序列; 生成树:某连通分量的极小连通子图; 生成森林:非连通图的各个连通分量的极小连通子图构成的集合。,无向图的连通分量和生成树,7.4 图的连通性问题,生成树的特征n 个顶点的连通网络的生成树有 n 个顶点、n-1 条边。,求生成树的方法DFS(深度优先搜索)和BFS(广度优先搜索),对于连通图,仅需

14、从图中任一顶点出发,进行DFS或BFS, 便可访问到图中所有顶点.对于非连通图,需从多个顶点出发进行搜索,而每一次 从一个新的起始点出发进行搜索过程中得到的顶点访问序 列恰为其各个连通分量中的顶点集.,求下图的深度优先生成树和广度优先生成树,7.4 图的连通性问题,v1,v6,v2,v5,v3,v8,v4,v7,v1,v6,v2,v5,v3,v8,v4,v7,无向图的连通分量和生成树,7.4 图的连通性问题,对非连通图,每个连通分量中的顶点集和遍历时走过的边一起构成若干棵生成树,这些连通分量的生成树组成非连通图的生成森林。,无向图的连通分量和生成树,7.4 图的连通性问题,v1,v6,v2,v

15、5,v3,v8,v4,v7,v9,v10,v12,v13,v11,v1,v6,v2,v5,v3,v8,v4,v7,v9,v10,v12,v13,v11,最小生成树,7.4 图的连通性问题,v1,v6,v2,v5,v3,v4,1,6,3,2,4,v1,v6,v2,v5,v3,v4,5,1,3,2,4,v1,v6,v2,v5,v3,v4,6,5,5,6,4,最小生成树,7.4 图的连通性问题,目标:在网的多个生成树中,寻找一个各边权值之和最小的生成树。,应用: n个城市建网,如何选择n1条线路,使总费用最少?,Kruskal(克鲁斯卡尔)算法 Prim(普里姆)算法,算法:,代价唯一,可以反证法证

16、明。 拓扑不唯一,取决于具体的无向图结构,克鲁斯卡尔(Kruskal)算法,7.4 图的连通性问题,先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中去,并使森林中不产生回路,直至森林变成一棵树为止。,克鲁斯卡尔(Kruskal)算法,7.4 图的连通性问题,v1,v3,v2,v4,v5,v6,5,1,3,2,4,普利姆(Prim)算法,7.4 图的连通性问题,(1) G=(V, E) 是一个具有 n 个顶点的连通网络,T=(U,TE)是 G 的最小生成树,其中 U 是 T 的顶点集,TE 是 T 的边集,U 和 TE 的初值均为空; (2)从 V 中任取一个顶点(假

17、定为 V1),将此顶点并入 U中,此时最小生成树顶点集 U=V1; (3)从那些其中一个端点已在 U 中,另一端点仍在 U 外的所有边中,找一条最短(即权值最小)的边,设该边为(Vi,Vj),其中 ViU,VjV-U,并把该边和顶点 Vj分别并入 T 的边集 TE 和顶点集 U; (4)如此进行下去,每次往生成树里并入一个顶点和一条边,直到 n-1 次后,把所有 n 个顶点都并入生成树 T 的顶点集 U 中,此时 U=V,TE中包含有( n-1 )条边;这样,T 就是最后得到的最小生成树。,普利姆(Prim)算法,v1,v3,v2,v4,v5,v6,5,1,3,2,4,v1,v3,v2,v4,

18、v5,v6,6,5,1,5,5,6,6,3,2,4,1.1 什么是数据结构,普利姆(Prim)算法,7.4 图的连通性问题,1 2 3 4 5 6,普利姆(Prim)算法,7.4 图的连通性问题,设计思路: 增设一辅助数组Closedge n ,每个数组分量都有两个域:,要求:使Colsedge i .lowcost = min( ( u ,vi ) ) u U,vi 在U中的邻点u,Closedge i ,V-U中顶点vi,u与vi之间对应的边权,从u1un中挑,1,2,3,4,5,6,1, 3,2, 4, 5, 6,1,3,6,2, 4,5,1,3, 6,4,2, 5,1,3,6,4,2,

19、5,1,3,6,4,2,5,1,3,起点,4,6,2,4,5,2,3,5,1 2 3 4 5 6,显然, Prim算法的时间效率O(n2),基于邻接矩阵的普里姆算法,7.4 图的连通性问题,struct VertaxType adjvex; /顶点编号VRType lowcost; / =Mincost(u,vi|uU) closeageMAX_VERTEX_NUM;Void MiniSpanTree_PRIM(MGraph G, VertexType u) k = LocateVex ( G, u ); / 顶点u为构造生成树的起始点,返回顶点u在图中的位置for ( j=0; jG.vex

20、num; +j ) / 辅助数组初始化if (j!=k) closedgej= u, G.arcskj.adj ; closedgek.lowcost = 0; / 初始,Uu,弧k,j的权值,基于邻接矩阵的普里姆算法,7.4 图的连通性问题,for (i=1; iG.vexnum; +i) /在其余顶点中选择k = minimum(closedge); / 求出T的下一结点(k)printf(closedgek.adjvex, G.vexsk); /输出生成树的边closedgek.lowcost = 0; / 第k顶点并入U集for (j=0; jG.vexnum; +j) if (G.arcskj.adj closedgej.lowcost) / 新顶点并入U后重新选择最小边closedgej=G.vexsk,G.arcskj.adj; / for / MiniSpanTree_PRIM,T(n)=O(n2),最小生成树,7.4 图的连通性问题,普里姆算法的时间复杂度为 O(n2),适于稠密图; 克鲁斯卡尔算法需对 e 条边按权值进行排序,其时间复杂度为 O(eloge),适于稀疏图。,Thank You !,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 网络科技 > 数据结构与算法

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报