其他分享
首页 > 其他分享> > 图的遍历

图的遍历

作者:互联网

6.5 图的遍历

​ 和树的遍历类似,图的遍历也是从图中某一顶点出发,按照某种方法对图中所有顶点访问且仅访问一次。 图的遍历算法是求解图的连通性问题、 拓扑排序和关键路径等算法的基础。
​ 然而,图的遍历要比树的遍历复杂得多。 因为图的任一顶点都可能和其余的顶点相邻接。 所 以在访问了某个顶点之后,可能沿着某条路径搜索之后,又回到该顶点上。 例如,图6.1(b)中 所示的 G2, 由于图中存在回路, 因此在访问了 v1 、 v2 、 v3 、 v4 之后,沿着边<v4, v1>又 可访问到 V1。 为了避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点。 为此,设一 个辅助数组visited[n] , 其初始值置为"false"或者0, 一 旦访问了顶点 Vi, 便置visited[i]为"true"
或者 1。
​ 根据搜索路径的方向,通常有两条遍历图的路径:深度优先搜索和广度优先搜索。 它们对无向图和有向图都适用。

6.5.1 深度优先搜索

1.深度优先搜索遍历的过程

(1)从图中某个顶点v出发, 访问v。

(2)找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。 以该顶点为新顶点,重 复此步骤, 直至刚访问过的顶点没有未被访问的邻接点为止。

(3)返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的 邻接点, 访问该顶点。

(4)重复步骤 (2) 和(3), 直至图中所有顶点都被访问过,搜索结束。

2.深度优先搜索遍历的算法实现

算法6.3 深度优先搜索遍历连通图

算法6.4 深度优先搜索遍历非连通图

算法6.5 采用邻接表表示图的深度优先搜索遍历

算法6.6 采用邻接表表示图的深度优先搜索遍历

3.深度优先搜索遍历的算法分析

分析上述算法,在遍历图时,对图中每个顶点至多调用一次 DFS 函数,因为一旦某个顶点被标志成巳被访问,就不再从它出发进行搜索。 因此,遍历图的过程实质上是对每个顶点查找其邻接点的过程,其耗费的时间则取决千所采用的存储结构。 当用邻接矩阵表示图时,查找每个顶点的邻接点的时间复杂度为 O(n2 ), 其中 n为图中顶点数。而当以邻接表做图的存储结构时,查找邻接点的时间复杂度为O(e), 其中e为图中边数。由此, 当以邻接表做存储结构时,深度优先搜索遍历图的时间复杂度为 O(n + e)。

6.5.2 广度优先搜索

1.广度优先搜索的过程:

(1) 从图中某个顶点v出发, 访问v。

(2) 依次访问v的各个未曾访问过的邻接点。

(3) 分别从这些邻接点出发依次访问它们的邻接点, 并使 “先被访问的顶点的邻接点“ 先千 ”后被访问的顶点的邻接点” 被访问。重复步骤(3), 直至图中所有已被访问的顶点的邻接点都被 访间到。
具体过程如下:

​ (1) 从顶点 v1 出发,访问 v1
​ (2) 依次访问 v1 的各个未曾访问过的邻接点 v2 和 v3
​ (3) 依次访问v2的邻接点v4和v5, 以及v3的邻接点v6和v7, 最后访问v4的邻接点vg。由千 这些顶点的邻接点均已被访问, 并且图中所有顶点都被访问, 由此完成了图的遍历。得到的顶点 访间序列为:
​ v1-v2-v3-v4-v5-v6-v7-v8

2.广度优先搜索遍历的算法实现

算法6.7 广度优先搜索遍历连通图

3.广度优先搜索遍历的算法分析

分析上述算法,每个顶点至多进一次队列。遍历图的过程实质上是通过边找邻接点的过程,因此广度优先搜索遍历图的时间复杂度和深度优先搜索遍历相同,即当用邻接矩阵存储时,时间复杂度为O(n2 ); 用邻接表存储时,时间复杂度为O(n+ e)。两种遍历方法的不同之处仅仅在于对顶点访问的顺序不同。

图的应用

6.6.1 最小生成树

​ 假设要在 n 个城市之间建立通信联络网,则连通 n 个城市只需要 n-1 条线路。这时, 自然会考虑这样一个问题, 如何在最节省经费的前提下建立这个通信网。

​ 在每两个城市之间都可设置一条线路,相应地都要付出一定的经济代价。n个城市之间,最多可能设置 n(n- 1)/2 条线路,那么, 如何在这些可能的线路中选择 n-1,以使总的耗费最少呢?

​ 可以用连通网来表示n个城市, 以及n个城市间可能设置的通信线路, 其中网的顶点表示城市,边表示两城市之间的线路,赋予边的权值表示相应的代价。 对于 n 个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网。 最合理的通信网应该是代价之和最小的生成树。 在一个连通网的所有生成树中,各边的代价之和最小的那棵生成树称为该连通网的最小代价生成树 (Minimum Cost Spanning Tree), 简称为最小生成树

​ 构造最小生成树有多种算法,其中多数算法利用了最小生成树的下列一种简称为MST的性质:假设N= (V, E)是一个连通网,U 是顶点集 V 的一个非空子集。若(u, v)是一条具有最小权值(代价)的边,其中uEU, vEV-U, 则必存在一棵包含边(u, v)的最小生成树。

​ 可以用反证法来证明。假设网N的任何一棵最小生成树都不包含(u, v)。设T是连通网上的一棵最小生成树,当将边(u, v)加入到 T中时,由生成树的定义,T中必存在一条包含(u, v)的回路。另一方面,由于T是生成树,则在T上必存在另一条边(u',v'), 其中u'EU,v'EV-U,且 u 和 u'之间、 v 和 v'之间均有路径相通。 删去边(u', v'), 便可消除上述回路, 同时得到另一棵生 成树兀因为(u,v)的权值不高于(u',v'), 则 T的权值亦不高于 T, T是包含(u,v)的一棵最小生成 树。 由此和假设矛盾。

普里姆 (Prim) 算法克鲁斯卡尔 (Kruskal) 算法是两个利用 MST 性质构造最小生成树的 算法。 下面先介绍普里姆算法。

算法6.8 普里姆算法

算法6.9 克鲁斯卡尔算法

标签:遍历,访问,算法,搜索,邻接,顶点
来源: https://www.cnblogs.com/Dear-bella/p/15878590.html