图论广度优先搜索

Posted 远洋号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论广度优先搜索相关的知识,希望对你有一定的参考价值。

前言

推出一个新系列,《看图轻松理解数据结构和算法》,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握。本系列包括各种堆、各种队列、各种列表、各种树、各种图、各种排序等等几十篇的样子。

关于图遍历

图遍历即图的遍历,指从图中任一顶点出发,对图中的所有顶点访问一次。图的遍历与树的遍历相似,但图的结构更加复杂,比如要考虑回路的情况。图的遍历操作是一种基本操作,很多其他操作都建立在图遍历基础之上。图的遍历算法主要有广度优先搜索和深度优先搜索,这里先看广度优先搜索。

广度优先搜索

广度优先搜索(Breadth First Search),简称BFS,又称宽度优先搜索。它是很多图的算法的原型,Dijkstra单源最短路径算法和Prim最小生成树算法的思想都与BFS的思想类似。BFS的时间复杂度为O(|V|+|E|),其中|V|为图的顶点数,|E|为图的边数。

核心思想

  1. 选择一个初始顶点v_i,并将其标记为已访问;

  2. 访问v_i的所有未被访问过的邻接点v_{i1},v_{i2},…,v_{it},并均标记为已访问;

  3. 按照v_{i1},v_{i2},…,v_{it}的顺序,依次访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问;

  4. 以此类推,直到图中所有与初始顶点v_i有路径相通的顶点都被访问;

  5. 如果图中的顶点还有未被访问的,则再选出其中一个作为起始顶点,继续执行步骤2到步骤4;

  6. 遍历结束。

搜索过程

在实现过程中需要用到一个队列和一个数组,队列用于保存所有未被检测的顶点,而数组用于标识哪些顶点已被访问,F表示未被访问,T表示已被访问。

对于一个拥有7个顶点的无向加权图,分别用0-6来表示图的每个顶点,因为遍历与边的权重无关,这里将权重值省略。

image

选择1作为初始顶点,将其加入队列中,队列头即是正在处理的顶点,并将数组对应元素标为T。

图论广度优先搜索
image

开始检测顶点1的每条边,首先是到达顶点0的边,

图论广度优先搜索
image

因为顶点0的访问标记为F,说明还未被访问过,于是将0加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

继续检测顶点1的其它边,这次是到达顶点2的边,

图论广度优先搜索
image

因为顶点2的访问标记为F,说明还未被访问过,于是将2加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

继续检测顶点1的其它边,这次是到达顶点3的边,

图论广度优先搜索
image

因为顶点3的访问标记为F,说明还未被访问过,于是将3加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

顶点1的所有边已经被访问过了,于是从BFS队列中将1移除,接着处理下一个顶点,即顶点0。

图论广度优先搜索
image

检测顶点0的每条边,首先是到达顶点1的边,

图论广度优先搜索
image

因为顶点1的访问标记为T,说明已经被访问过,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

继续检测顶点0的其它边,这次是到达顶点2的边,因为顶点2的访问标记为T,说明已经被访问过,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

顶点0的所有边已经被访问过了,于是从BFS队列中将0移除,接着处理下一个顶点,即顶点2。

图论广度优先搜索
image

检测顶点2的每条边,首先是到达顶点0的边,因为顶点0的访问标记为T,说明已经被访问过,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

继续检测顶点2的其它边,这次是到达顶点1的边,因为顶点1的访问标记为T,说明已经被访问过,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

继续检测顶点2到顶点3的边,因为顶点3的访问标记为T,说明已经被访问过,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

继续检测顶点2到顶点4的边,

图论广度优先搜索
image

因为顶点4的访问标记为F,说明还未被访问过,于是将4加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

继续检测顶点2到顶点5的边,

图论广度优先搜索
image

因为顶点5的访问标记为F,说明还未被访问过,于是将5加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

顶点2的所有边已经被访问过了,于是从BFS队列中将2移除,接着处理下一个顶点,即顶点3。

图论广度优先搜索
image

顶点3相邻的所有顶点(1、2、4、5)的访问标记都为T,BFS队列和数组都不做任何更改。继续处理顶点4。

图论广度优先搜索
image

此时顶点2和顶点3的访问标记都为T,BFS队列和数组都不做任何更改。当检测顶点4到顶点6时,

图论广度优先搜索
image

因为顶点6的访问标记为F,说明还未被访问过,于是将6加入到BFS队列中,同时将访问标记改为T。

图论广度优先搜索
image

顶点4的所有边已经被访问过了,于是从BFS队列中将4移除,接着处理下一个顶点,即顶点5。顶点5相邻的所有顶点(2、3、6)的访问标记都为T,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

顶点5的所有边已经被访问过了,于是从BFS队列中将5移除,接着处理下一个顶点,即顶点6。顶点6相邻的所有顶点(4、5)的访问标记都为T,BFS队列和数组都不做任何更改。

图论广度优先搜索
image

最终的结果如下。

image


--------------------------------------

跟我交流:

-------------推荐阅读------------







以上是关于图论广度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章

图论广度优先搜索

SDUT 2142 TEST数据结构实验之图论二:基于邻接表的广度优先搜索遍历

基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

networkx图论Breadth First Search广度优先搜索遍历BFS,基于队列,Python

networkx图论Depth First Search广度优先搜索遍历DFS,基于栈,Python

图论:图的四种最短路径算法