你所在的位置: 首页 > 正文

C语言:数据结构-图的广度优先搜索遍历

2019-07-09 点击:977
通博老虎游戏tb官网平台

广度优先搜索遍历

(1)广度优先搜索遍历的定义

广度优先搜索遍历类似于逐层遍历,其遍历过程如下:

1.访问初始点vi,并标记它已被访问,访问所有未访问过的vi的邻居(顺序可以是任意的),假设vi1,vi2,vit,并且标记已被访问参观。

2.然后,根据邻居的访问顺序,访问V11,V22, Vit未访问的所有邻居,直到访问了所有顶点。

(2)广度优先搜索遍历过程

接下来,结合图5和图6中所示的有向图G8分析从v0开始的广度优先搜索遍历的过程。 7-10。

146546b8d2c24de4af3dc85a41cb17a5

1.访问初始点v0并将其标记为已访问;

2.访问v0的所有不需要的邻居v1和v2,并将它们标记为已访问;

3.访问顶点v1的所有未访问的邻居v3,v4和v5,并将其标记为已访问;

4.访问顶点v2的所有未访问的邻居v6(已访问其两个邻居v5中的一个)并将其标记为已访问;

5.访问顶点v3的所有未访问的邻居v7(仅访问过一个邻居)并将其标记为已访问;

6.访问顶点v4未访问过的所有邻居。由于访问了v4的邻居v7(仅一个),因此该步骤不访问任何顶点;

7.访问顶点v5的所有未访问的邻居v8并将其标记为已访问;

8.访问顶点v6未访问过的所有邻居。由于只访问了v6的一个邻居v8,因此该步骤不访问任何顶点;

9.依次访问v7和v8的所有未访问的邻居,因为它们没有邻居(即边缘邻居),因此整个遍历过程在此结束。

从有向图G8的广度优先搜索遍历的上述过程分析可以看出,从初始点v0访问顶点的顺序是:v0,v1,v2,v3,v4,v5,v6, v7,v8。

(3)广度优先搜索遍历的算法描述

在广度优先搜索遍历中,首先访问首先访问的顶点,因此在算法的实现中需要队列来记住依次访问的顶点。算法启动时,访问初始点vi并将其插入队列。从队列中删除每个元素后,依次访问尚未访问过的每个邻居,然后排队,这样当队列为空时?耸保硎舅芯哂新肪兜亩サ阋逊梦食跏嫉悖惴ㄔ诖舜崾?

在下文中,邻接矩阵和邻接列表分别用作图的存储结构,以给出相应的广度优先搜索遍历算法。类似地,算法中使用的访问的标签数组[MaxVertexNum]是整个数量。

相邻矩阵广度优先搜索遍历算法

Void bfs1(adjmatrix GA,int i,int n)

/*从初始点vi开始,广度优先搜索由邻接矩阵GA */

表示的图形

{

/*定义一个顺序队列Q,其元素类型应为整数,初始化队列为空*/

Int Q [MS]; //MS是预定义的符号常量

Int front=0,rear=0;

/*访问初始点vi,并标记已访问的初始点vi */

Printf('%d',i);

访问了[I]=1;

/*输入已访问团队的初始点编号*/

后部=(背面+ 1)%MS;

如果(前==后){printf(“队列空间耗尽!\ n”);出口(1);}

Q [后]=I;

/*队列不为空时循环处理*/

而(前!=后方){

Int j,k;

/*删除团队的第一个元素。第一次执行时的k值为i */

前面=(前+ 1)%MS; K=Q [前];

/*依次搜索vk的每个可能的相邻点*/

对于(j=0; j

如果(GA [k] [j]!=0&& GA [k] [j]!=MaxValue&&!visit [j]){

Printf('%d',j);/*访问不相关的邻居vj */

访问[J]=1;/*标记vj已被访问*/

后部=(背面+ 1)%MS;/*修改尾指针*/

如果(前==后){printf(“队列空间耗尽!\ n”);出口(1);}

Q [后]=j的;/* vertex number j enqueue */

}

}

}

}

邻接表广度优先搜索遍历算法

Void bfs2(adjlist GL,int i,int n)

/*从初始点vi开始,广度优先搜索由邻接列表GL */

表示的地图

{

/*定义一个顺序队列Q,其元素类型应为整数,初始化队列为空*/

Int Q [MS]; //MS是预定义的符号常量

Int front=0,rear=0;

Printf('%d',i);

访问了[I]=1;

/*输入已访问团队的初始点编号*/

后部=(背面+ 1)%MS;

如果(前==后){printf(“队列空间耗尽!\ n”);出口(1);}

Q [后]=I;

/*队列不为空时循环处理*/

而(前!=后方){

Int j,k;

结构edgenode * p;

/*删除团队的第一个元素。第一次执行时的k值为i */

前面=(前+ 1)%MS; K=Q [前];

P=GL [K];/*采用vk邻接列表的标题指针*/

/*依次搜索vk的每个可能的相邻点*/

而(对!=NULL){

Int j=p-> adjvex;/* vj是vk */

的邻接点

如果(!visited [j]){/*如果没有访问vj,它将被处理*/

Printf('%d',j);

访问[J]=1;

后部=(背面+ 1)%MS;/*修改尾指针*/

如果(前==后){printf(“队列空间耗尽!\ n”);出口(1);}

Q [后]=j的;/* vertex number j enqueue */

}

P=对 - >接着,/*使p指向vk邻接列表的下一个边缘节点*/

}

}

}

将上述两种算法与图1的(a)和(b)组合。在图7-9中,可以看出,从顶点v1获得的广度优先搜索遍历的顶点序列分别是以下序列。

顺序1:1,0,4,5,6,2,3

序号2:1,6,5,4,0,2,3

4)算法性能分析

与图的深度优先搜索遍历一样,对于图的广度优先搜索遍历,如果使用邻接矩阵,则时间复杂度为O(n2),并且如果使用邻接列表,则时间复杂度是O(e),二是人的空间复杂度是O(n)。

当从图的某个顶点执行广度优先搜索遍历时,访问每个顶点的顺序对于邻接矩阵是唯一的,并且对于邻接列表,它可以根据邻接列表而不同,这也是相关的到图表。深度优先搜索遍历也是如此。

(5)遍历非连通图

上面讨论的图的深度优先搜索遍历算法和图的广度优先搜索遍历算法。对于无向图,如果无向图是连通图,则如果无向图是非连通的,则可以访问图中的所有顶点。图只能访问初始点的连通分量中的所有顶点,并且其他连接组件中的顶点无法访问。为了访问图中的所有顶点,有必要从每个其他连通组件中选择初始点以分别执行搜索遍历。对于有向图,如果图中有从初始点到每个顶点的路径,则可以访问图中的所有顶点,否则无法访问所有顶点,也不需要访问它。选择顶点中的一些顶点作为初始点,并执行搜索遍历,直到访问了图中的所有顶点。

为了能够访问图中的所有顶点,该方法非常简单,只要将图中未访问的每个顶点用作初始点,就可以调用上述任何算法。也就是说,在函数中执行以下for语句。

对于(i=0; i

如果(!访问[I])

DFS1(GA,I,N); //你也可以调用dfs2,bfs1或bfs2函数

如果连接了无向图,或者存在从有向图的顶点v0到每个剩余顶点的路径,则循环语句仅执行一次调用(即,dfs1(ga,0,n)调用)。结束遍历过程,否则您将不得不执行多次调用以结束遍历过程。对于无向图,每个调用将遍历连接的组件,以及调用进程指示图表具有多少独立连接组件的次数。

日期归档
tb0004通博 版权所有© www.pecoviedo.com 技术支持:tb0004通博 | 网站地图