图论广度优先搜索

作者:超人汪小建(seaboat)

出处:https://blog.csdn.net/wangyangzhizhou/column/info/25184/2


关于图遍历

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

广度优先搜索

广度优先搜索(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

赞(0) 打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。Java 技术驿站 » 图论广度优先搜索
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

关注【Java 技术驿站】公众号,每天早上 8:10 为你推送一篇技术文章

扫描二维码关注我!


关注【Java 技术驿站】公众号 回复 “VIP”,获取 VIP 地址永久关闭弹出窗口

免费获取资源

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏