广度优先搜索的一些学习笔记

什么是图?
图由节点和边组成。一个节点可能与众多节点直接相连,这些节点也被称为邻居。
图用于模拟一组连接。
例如从双子峰到金门大桥的出行路线图:
在这里插入图片描述

由上面这个图,我们要找出从双子峰到金门大桥的最短换乘路线,这个问题被称为最短路径问题,而解决最短路径问题的算法被称为广度优先搜索。

广度优先搜索

广度优先搜索是一种用于图的查找算法。

它可用于解决两类问题:
1、从某节点出发,有去往下一节点的路径吗?
2、从某节点出发,前往下一节点的哪条路径最短?

想要实现广度优先搜索首先我们要解决优先顺序的实现问题,很显然,在这里使用队列是很明智的选择。
然后我们需要实现图,图由多个节点组成,很显然,在这里我们可以使用散列表去表示图的关系,将节点映射到其所有的邻居。

运行时间

将一个元素添加到队列需要的时间是固定的,为O(1),因此对每个元素都这样做需要的总时间为O(元素个数),在图里面从一个节点到另一个节点需要的时间是O(边数)。所以广度优先搜索的运行时间为O(元素个数 + 边数),这通常写作O(V + E),其中V为顶点数,E为边数。

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

代码

这里以经营芒果农场需要将芒果卖给芒果销售商为例,我们需要通过Facebook去查找芒果销售商:

# 首先创建表示人际关系的图  
graph = {}  
graph['you'] = ['alice', 'bob', 'claire']  
graph['bob'] = ['angel', 'peggy']  
graph['alice'] = ['peggy']  
graph['claire'] = ['tom', 'jonny']   
graph['angel'] = []
graph['peggy'] = []
graph['tom'] = []  
graph['jonny'] = []  

# 然后创建一个队列,我们可以使用双端队列deque
from collections import deque  

def search_mango(name):
	search_queue = deque()  
	# 将‘你’的邻居都加入到这个搜索队列中
	search_queue += graph['you']
	# 创建一个数组用于记录检查过的人
	searched = []

	# 只要队列不为空,就取出其中的第一个人
	while search_queue:  
		person = search_queue.popleft()  
		# 检查这个人是否是芒果销售商,函数person_is_seller可以自己尝试去实现一下
		if person not in searched:  # 仅当这个人没被检查过时才检查
			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')  

猜你喜欢

转载自blog.csdn.net/june_young_fan/article/details/83216224