第六章-广度优先搜索
1. 广度优先搜索回答两类问题
①从节点A出发,有前往节点B的路径吗?
②从节点A出发,前往节点B的哪条路径最短?
BFS找的是最短的路径。
2. 队列
按添加顺序查找时,才能找到最短路径。
实现该目的可用队列这一数据结构。队列只支持入队和出队,不能随机访问队列中的元素。
3. 实现图
散列表(hash table)可以用来表示节点和邻近节点相连的关系。(它能将键映射到值)
以书中“你要在人际关系网中寻找芒果销售商”为例,把“你”这个节点映射到所有邻居可表示为:
1 graph = {} 2 graph["you"] = ["alice", "bob", "claire"] # 注意:“你”被映射到一个数组,graph["you"]是一个数组,其中包含“你”的所有邻居
类似地,邻居的邻居也可用上述形式表示。另,散列表是无序的,键值对添加顺序无关紧要。
4. 用python实现BFS例子
(注:双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。)
from collections import deque # 图 graph = {"you": ["alice", "bob", "claire"], "bob": ["anuj", "peggy"], "claire": ["thom", "johnny"], "alice": ["peggy"], "anuj": [], "peggy": [], "thom": [], "johnny": []} def search(name): search_queue = deque() search_queue += graph[name] searched = [] # 记录检查过的人,以免重复 while search_queue: # 只要队列不为空 person = search_queue.popleft() # 取出第一个人 if person is not searched: # 只检查没被标记过的人 if person_is_seller(person): print(person + " is seller") return True else: search_queue += graph[person] searched.append(person) return False def person_is_seller(name): return name[-1] == 'm' # 假如名字最后一个字母为m的人是seller search("you")
5. 运行时间
O(V+E) 顶点数(vertice)加边数(edges)
6. 拓扑排序
使用拓扑排序可以根据图创建一个有序列表。
(以家谱为例)家族树是“树”,树是一种特殊的图。

浙公网安备 33010602011771号