数据结构和算法
基于《算法图解》—Aditya Bhargava 和《数据结构》—严蔚敏

第6章广度优先搜索

6.1 简介
广度优先搜索—breadth-first search,BFS.
主要内容图和队列。
广度优先搜索能让你能够找出两样东西之间的最短距离,比如:编写国际跳棋AI(Artificial Intelligence),计算最少走多少步可以获胜;或者根据你的人际关系网络找到关系最近的医生。

需要两个步骤:

(1)使用图来建立问题模型。
(2)使用广度优先搜索解决问题。

6.2 什么是图
图由节点和边组成。一个节点可能与众多节点直接相连,这些节点被称为邻居。

6.3 广度优先搜索
广度优先搜索是一种用于图的查找算法,可帮助回答两类问题:

  • 第一类问题:从节点A出发,有前往节点B的路径吗?
  • 第二类问题:从节点A出发,前往节点B的哪条路径最短?

假设你经营着一个芒果农场,需要寻找芒果销售商,以便将芒果卖给他。为此,你可在朋友中查找。

首先创建一个朋友名单,然后依次检查名单中的每个人,是否是芒果销售商:

假设你没有朋友是芒果销售商,那么你就必须在朋友的朋友中查找。

检查名单中的每个人时,你都将其朋友加入名单。

6.3.1 查找最短路径
一度关系胜过二度关系,二度关系胜过三度关系,以此类推。

广度优先搜索不仅查找从A到B的路径,而且找到的是最短的路径。

只有按添加顺序查找时,才能实现这样的目的。

队列(queue):实现按添加顺序进行检查的数据结构。

6.3.2 队列
队列能够实现按添加顺序进行检查的需求。
队列不能随机访问,只能支持两种操作:入队和出队。

先加入的元素将先出队并被检查。

队列是一种先进先出(First In First Out)的数据结构;
栈是一种后进先出(Last In First Out)的数据结构。

6.4 实现图
图是由多个节点组成,需要使用代码来实现图。
每个结点都与邻近结点相连,散列表可以很好的实现这种关系。

散列表将键映射到值,比如将你这个节点映射到所有邻居。

表示这种映射关系的Python代码如下,

graph = {}  #前面提到Python中是用字典来实现散列表。{}表示生成空字典。
graph["you"] = ["alice", "bob", "claire"]
#"you"被映射到了一个数组,因此graph["you"]是一个数组,包含了"you"的所有邻居。

graph = {}
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
#散列表是无序的,因此添加键-值对的顺序不关紧要。

有向图(directed graph):有一个节点指向相邻节点,单向关系。上图中Anuj,Peggy,Thom,Jonny都没有邻居,因为他们没有指向其他节点。

无向图(undirected graph):没有箭头,直接连接的节点互为邻居。
下面两图等效:

6.5 实现算法
队列实现原理

#首先使用函数deque来创建一个双端队列。
from collections import deque
def search(name):search_queue = deque() #创建一个队列search_queue += graph[name]  #将邻居都加入到这个搜索队列中。searched = []  #这个数组用于记录检查过的人,避免无限循环。#进行对每个人进行检查while search_queue: #只要队列不为空,person = search_queue.popleft() #就取出其中的第一个人(左端)if person not in searched:  #仅当这个人没检查过时才检查if person_is_seller(person): #检查此人是否是芒果销售商print(person + "is a mango seller!")return Trueelse:search_queue += graph[person] #如果不是,将此人的朋友(相邻节点)都加入搜索队列。searched.append(person) #并将此人添加到以搜索过的列表,避免再次搜索此人。return False  #如果到达这里,说明队列中没有芒果销售商#假设以姓名结尾为m的人为芒果销售商。
def person_is_seller(name):return name[-1] == 'm' #名字末尾为msearch("you") #函数调用

为什么要避免被重复搜索(检查):
上图中Peggy既是Alice的朋友又是Bob的朋友,因此她将被加入队列两次;因此,搜索队列将包含两个Peggy。

检查完一个人后,应将其标记为已检查,且不再检查;如果不这样做,就可能会导致无限循环。

因为搜索队列将在包含你和包含Peggy之间反复切换,从而造成无限循环。

列表是有序的。如果任务A依赖于任务B,在列表中任务A就必须在任务B后面,这被称为拓扑排序,使用它可根据图创建一个有序表。

6.5.1 树
树是特殊的图,其中没有往后指的边。

树是图的子集,树都是图,图不一定是树。

6.6 小结

  • 队列是先进先出。
  • 栈是后进先出。
  • 注意避免导致无限循环。

——持续修改完善中…

06-广度优先搜索:图、队列相关推荐

  1. 数据结构之广度优先搜索(队列实现)问题

    Description 定义一个二维数组: int maze[5][5] = {0, 1, 0, 0, 0,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0, 1, 1, 1, 0,0, 0 ...

  2. 6.1 图的深度优先和广度优先搜索

    图的广度优先搜索 图的的搜索算法主要分为广度优先搜索(breadth-first search或BFS)和深度优先搜索(depth-first search或DFS).首先讨论广度优先搜索算法. 称之 ...

  3. 广度优先搜索(BFS)及其matlab代码

    文章目录 前言 一.广度优先搜索是什么? 二.广度优先搜索的基本思路即其matlab代码 1.广度优先搜索的基本思路 2.matlab代码 总结 前言   广度优先搜索常被拿来与深度优先搜索进行比较, ...

  4. 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS)

    广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS) 1. 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first searc ...

  5. 深度优先搜索遍历与广度优先搜索遍历

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 深度优先 ...

  6. 广搜(广度优先搜索BFS)

    广度优先搜索 广度优先搜索算法(又称宽度优先搜索)是最简便的图的搜索算法之一,其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果.换句话说,它并不考虑结果的可能位置 ...

  7. 深度优先搜索(DFS)与广度优先搜索(BFS)

        深度优先搜索(Depth-First Search)和广度优先搜索(Breadth-First Search)都是对图进行搜索的算法,两者都是从起点开始顺着边搜索,直到找到结果为止,区别在于两 ...

  8. 广度优先搜索以及C++实现

    一.引入两个问题 给出图1从任意一点开始的广度优先搜索遍历的序列, (1)设置BFS返回值为向量的代码: (2)设置BFS无返回值,同时点集用字符串表示,要求输出结果打印到屏幕上 图1 岛屿数量问题( ...

  9. python扫雷 广度优先_基于邻接矩阵的广度优先搜索遍历(BFS)

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索( ...

  10. LeetCode-365.水壶问题 广度优先搜索、费蜀定理

    这里是题目描述:LeetCode-365.水壶问题 方法一:广度优先搜索 对于容量分别为x和y的水壶h1.h2,我们将两水壶分别有v1和v2升水作为一种状态,可以从当前状态出发经过一定操作(倒水.装水 ...

最新文章

  1. 技术博客(初用markdown)。
  2. post提交的数据几种编码格式
  3. 小程序promise封装post请求_微信小程序用promise封装请求
  4. NetBeans 时事通讯(刊号 # 60 - Jun 21, 2009)
  5. 【sklearrn学习】朴素贝叶斯
  6. java中inputstream_java中InputStream String
  7. com.microsoft.sqlserver.jdbc.SQLServerException: 索引 7 超出范围。
  8. MDI窗体简单方法(调用,闪屏)
  9. 会议交流 | 人工智能与机器学习创新峰会 - 知识图谱与图神经网络分会
  10. PB-treeview基本属性事件函数
  11. python int占几个字节_int占几个字节(c语言)?
  12. 终于搞定阿里云ftp的问题
  13. 游戏IP手册:游戏IP的内涵元素
  14. 公众号滑动图代码_微信公众号文章滑动图片怎么做的呢?
  15. 第二篇:Cydia添加源和安装软件
  16. nginx 开机启动报错An error occurred.
  17. 组员组长mysql_GitHub - gzh51906/ManKeZhan: 组长:黄林芳 组员:陈炜,王佳伟
  18. 美味连连-QQ游戏辅助-简单实用的QQ游戏美味连连辅助(非外挂)
  19. linux grub配置文件丢失,linux grub.conf文件丢失恢复
  20. php 七牛时间戳防盗链,时间戳防盗链

热门文章

  1. 服务器应用服务为何卡顿?原来是内存耗尽惹的祸!
  2. asp.net core 从 3.0 到 3.1
  3. 使用 DotNet CLI 创建自定义的 WPF 项目模板
  4. 从壹开始 [ Id4 ] 之一║ 授权服务器 IdentityServer4 开篇讲计划书
  5. eShopOnContainers 知多少[9]:Ocelot gateways
  6. .NET Core2使用Azure云上的Iot-Hub服务
  7. 实体类的动态生成(一)
  8. 大部分Intel hardware intrinsic 将在 .NET Core 2.1 中启用
  9. vscode 头文件包含问题_WSL+VSCode = Linux ?
  10. 十大排序总结(js实现、稳定性、内外部排序区别、时间空间复杂度、冒泡、快速、直接选择、堆、直接插入、希尔、桶、基数、归并、计数排序)