广度优先搜索

Catherine ·
更新时间:2024-11-15
· 766 次阅读

1、广度优先搜索

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

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

假设M经营一个鱼塘,需要找销售商,以便卖掉养好的鱼。这时,M联系销售商有两种方式:

1、通过M的通讯录联系,看是否有销售商。 2、通过M的通讯录联系朋友,是否有销售方的联系方式。

假设,M的通讯录有A,B,C的联系方式,A有M,N,G的联系方式,B有M,N的联系方式,C有M,P,K的联系方式。

M A, B, C
A M, N, G
B M, N
C M, P, K

那此时M怎么找到销售商呢?(假设K是销售商)
假设,朋友是一度关系,朋友的朋友是二度关系。

一度关系有:A ,B,C 二度关系有:M,N,G,P,K

对于M来说,M将在一度关系查找,再到二度关系中查找,因此这样找到的是关系最近的销售商。对于广度优先遍历不仅能查找从A到B的路径还能找到最短路径。 使用广度优先搜索再好不过了。为了能够顺序一一检查是否为销售商,有一种数据结构可以解决这个问题——队列。队列是一种先进先出的数据结构,而栈是一种后进先出的数据结构。
散列表能能映射人与人之间的关系,且查找速率快,并且是无序的,不用考虑你的通讯录中先查验谁。散列表可以参考:散列表,表示这种映射关系的Python代码如下:

graph = {} graph['M'] = ['A','B','C'] graph['A'] = ['M', 'N', 'G'] graph['B'] = ['M', 'N'] graph['C'] = ['M', 'P', 'K'] graph['N'] = [] graph['G'] = [] graph['P'] = [] graph['K'] = []

由此看出人与人之间的映射关系构建了一个有向图,人是节点,映射关系是边。

算法实现: from collections import deque graph = {} graph['M'] = ['A','B','C'] graph['A'] = ['M', 'N', 'G'] graph['B'] = ['M', 'N'] graph['C'] = ['M', 'P', 'K'] graph['N'] = [] graph['G'] = [] graph['P'] = [] graph['K'] = [] #以上内容也可以使用字典存放 def person_is_seller(person): return person == 'K' def search(name): search_queue = deque() #创建一个队列 search_queue += graph[name] #将name的邻居都加入到这个搜索队列中 searched = [] #用于记录已经检查过的人 while search_queue: person = search_queue.popleft() #取出其中第一个人 if person not in searched: if person_is_seller(person): print(person,'是销售者') return True else: search_queue += graph[person] searched.append(person) # 将这个人标记为检查过 return False if __name__ == '__main__': search('M') 算法的运行时间到底是一个什么量级呢?

通过整个人际关系网中搜索销售商,就意味着将沿着每条边前行,因此运行时间最少为O(边数),除此之外,还使用了一个队列,其中包含要检查的每个人。将一个人添加到队列的时间是固定的,即为O(1),因此对每个人都是这样做需要的总时间为O(人数),所以广度优先搜索的运行时间为O(人数+边数)O(人数+边数)O(人数+边数),通常写作O(V+E)O(V+E)O(V+E),其中V为顶点数,E为边数。

补充词汇:拓扑排序,可以这么理解如果任务A依赖任务B,在列表中A就必须在任务B前面。


作者:随风飘飘天地任我逍遥



广度优先搜索

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章