图论广度优先搜索

前言

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

关于图遍历

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

广度优先搜索

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

核心思想

  1. 选择一个初始顶点《图论广度优先搜索》,并将其标记为已访问;
  2. 访问《图论广度优先搜索》的所有未被访问过的邻接点《图论广度优先搜索》,并均标记为已访问;
  3. 按照《图论广度优先搜索》的顺序,依次访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问;
  4. 以此类推,直到图中所有与初始顶点《图论广度优先搜索》有路径相通的顶点都被访问;
  5. 如果图中的顶点还有未被访问的,则再选出其中一个作为起始顶点,继续执行步骤2到步骤4;
  6. 遍历结束。

搜索过程

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

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

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

《图论广度优先搜索》

最终的结果如下。

《图论广度优先搜索》

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

我的开源项目汇总(机器&深度学习、NLP、网络IO、AIML、mysql协议、chatbot)

为什么写《Tomcat内核设计剖析》

我的2017文章汇总——机器学习篇

我的2017文章汇总——Java及中间件

我的2017文章汇总——深度学习篇

我的2017文章汇总——JDK源码篇

我的2017文章汇总——自然语言处理篇

我的2017文章汇总——Java并发篇

跟我交流,向我提问:

《图论广度优先搜索》

欢迎关注:

《图论广度优先搜索》

    原文作者:算法小白
    原文地址: https://juejin.im/post/5c16fd82e51d452f8e603d97
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞