广度优先搜索java_图论广度优先搜索

关于图遍历

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

广度优先搜索

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

核心思想

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

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

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

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

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

遍历结束。

搜索过程

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

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

1c71cdaf6d3a277ebec2e491ac7e6d0f.png

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

13e15d42d360b4da0067dbe23cd7aed9.png

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

274a39fef2ee5338b2856de3f5b78cf4.png

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

1079ea6e4925e015fe75489182162a81.png

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

597e73844a3c016acd1a6f736aafc9a4.png

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

971967087681356d47926aa6895be694.png

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

9951aff346718df83130f8d87de1a399.png

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

7ffa404367efd87fcced1676b9aad7ad.png

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

8af368ac8e369db18e3b255e9747816f.png

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

4a03b22e40b289a6ed0b6bf298e41ca7.png

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

590d7bcd01019540944c3f2bcf45dd4c.png

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

60267c0bc29974b9bd52b9dc9e716cfb.png

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

475f68a0b32b35b68c7dabfae6d0f4d1.png

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

9be5600d2562a1c37b3b9c6a72eaebca.png

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

4fca699c40c6e1bfc271576219358e61.png

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

9c5862cbe40e030529fd6bae322edead.png

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

d2847d58a00a6a84b8185ff8968b105f.png

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

170332ebad611a087d38c3fcccd19176.png

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

83b6c1fed85ed0a13a7c2b22bbda760c.png

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

4ac5bfcee95e3e1c2f7c711ce657e342.png

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

bff2f102e25f4649da53c2e8819a7e11.png

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

e206d3e715bcfe99f731739132e28325.png

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

c3f44530b97f847b7c0e821c20cd9a28.png

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

333209bfe8d298de3f47d728cdf81f33.png

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

a7341a174e62f90510ff3f433bc27bba.png

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

ca9c2f7f231f9d7e86d7ac724c680b5e.png

最终的结果如下。

30a040b3885b1c9367d582f951048cfa.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值