图简介
图模拟一组连接,图由节点和边组成。一个结点可能与众多结点直接相连,这些节点被称为邻居。图用于模拟不同的东西是如何相连的。
比如模拟谁欠谁钱这个问题:
从这个图里可以看出Siri欠小v钱,小v欠小布钱等。小v是Siri的邻居,小布不是Siri的邻居,因为它们没有直接相连。在广度优先算法中,我们就需要用到图。
广度优先搜索(bfs)
广度优先搜索是一种用于图的查找算法,可以帮助回答两类问题:
- 第一类问题:从节点A出发,有前往B的路径吗
- 第二类问题:从节点A出发,前往B的哪条路径最短
与广度优先搜索经常并在一起的另一种搜索方法还有深度优先搜索
广度优先搜索与深度优先搜索区别
以族谱为例分析两种搜索方法
在族谱中找到外公
深度优先搜索:
搜索方法:
沿着一条路走到底,直到无路可走,还没有找到目标,再返回上一个节点去搜索上一个节点的其他路径
依旧没找到外公·,继续返回上一节点,搜索其他路径
广度优先搜索:
搜索方法:
与上相似,上面以深度为第一标准,而bfs则是以广度为第一标准,搜索范围从起点开始,即先检查一度关系,再检查二度关系:
没找到,则看下一层级:
通过上面对比,很容易可以看出若要寻找从A到B的最短路径,则使用bfs是比dfs要容易的。广度优先搜索不仅查找A到B的路径,而且找到的是最短的路径
队列
引言
在广度优先搜索中,经常会增加搜索对象,例如在你的人际关系中找到一个芒果销售商,如果你和你的朋友们都不是芒果销售商,则需要在你朋友的朋友中进行搜索,这是就需要在你搜索的图中添加成员,按添加顺序进行检查。有一种能实现这种目的的数据结构,那就是队列。
队列的工作原理与现实生活中的排队完全相同。队列只支持两种操作:入队和出队。
队列:
出队:
入队:
队列是一种先进先出(First In First Out,FIFO)的数据结构
广度优先搜索算法工作原理
以寻找芒果销售商为例
1.创建一个队列,用于存储要检查的人
2.从队列中弹出一个人
3.检查这个人是芒果销售商吗
4.
{
是
,
结束搜索,大功告成
不是
,
将这个人的所有邻居都加入队列
\begin{cases} 是, & \text{结束搜索,大功告成} \\ 不是, & \text{将这个人的所有邻居都加入队列} \\ \end{cases}
{是,不是,结束搜索,大功告成将这个人的所有邻居都加入队列
5.回到第二步
6.如果队列为空,就说明你的人际关系网中没有芒果销售商
这个算法将不断执行,直到满足以下条件之一:
- 找到一位芒果销售商
- 队列变成空的,这意味着你的人际关系网中没有芒果销售商
bfs代码实现
def search(name):
search_queue = deque()
search_queue += graph[name]
searched = []//用这个数组来记录检查过的人
while search_queue:
person = search_queue.popleft()
if person not in searchded://仅当这个人没检查过才检查
if person_is_seller(person):
print person + " is a mango seller!"
return True
else:
search_queue += graph[person]
searched.append(person)//将这个人标记为检查过
return False
search("you")
关于广度优先搜索的知识就先介绍到这儿,如有问题,敬请指正,祝大家学习愉快!