本篇博客介绍广度优先搜索 (breadth-first search, BFS)
广度优先搜索
-
一种图算法
-
可回答用于两类问题:
- 从节点A出发,有前往节点B的路径吗?
- 从节点A出发,前往节点B的路径中哪条路径最短?
-
本质上就是一个队列(先进先出,也称为FIFO – First In First Out)
具体实例
*上图源于《算法图解》
问题: 利用BFS找到最近的名字结尾带M的朋友
算法思路:
- 从自己开始,依次检查自己的一度好友
- 若一度好友中没有符合条件的名字,则将好友的好友加入待检查队列中
- 待所有一度好友检查完后,开始检查二度好友。
- 重复以上三步,直到找到符合条件的名字或者全部检查完发现没有符合条件的名字
代码实现:
from collections import deque
def if_seller(name):
return name[-1] =='m'
graph = {}
graph['you'] = ['alice','bob','claire']
graph['bob'] = ['anuj','peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom','jonny']
graph['peggy'] = []
graph['thon'] = []
graph['jonny'] = []
graph['anuj'] = []
def search(name):
search_queue = deque() #创建一个双端队列,比list有更低的空间和时间复杂度
search_queue += graph[name]
searched = [] #用于放已检查过的人,没有这步会导致无限循环
while search_queue:
person = search_queue.popleft()
if person not in searched:
if if_seller(person):
print(f'Found {person}')
return True
else:
search_queue += graph[person]
return False
search('you')