第六章-广度优先搜索

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. 拓扑排序

使用拓扑排序可以根据图创建一个有序列表。

(以家谱为例)家族树是“树”,树是一种特殊的图。

 

posted @ 2020-04-20 18:20  来一个烤包子  阅读(120)  评论(0)    收藏  举报