简介

广度优先搜索算法(Breathed First Search)是一种搜索算法。原理就是从树的根节点开始去遍历所有节点,从而找出最短路径。

使用范围
  • 可以用来走迷宫,在游戏领域中可以用来做自动寻路功能
  • 可以用来编写跳棋AI,计算多少步能获胜
  • 也可以用来根据自己的人际关系网络查找到关系最近的医生

图由节点和边组成。一个节点可能与众多节点直接相连
图用于模拟不同的东西是如何相连的。

类似这样模拟了欠债关系的就是图

在遇到能用广度优先搜索算法解决问题时,我们可以先借助图来建立问题模型,然后再通过算法去解决问题。

图只是用来模拟问题模型,并不是最终答案

树形结构也是一种图,与其他图不同的是它不会往后指。

也就是说遇到问题后,我们可以通过图把问题的关键点放在节点上。用散列表把这些点按照图的结构存储起来,然后再执行搜索找到最佳路径。

可能看文字描述有点太抽象,刷几道题来找找感觉!

实践

题1 从好友名单中找出关系最近医生

解题思路:
1. 创建一个队列,用于存储查找名单
2. 从队列中弹出一个人
3. 检查这个人是不是医生
4. 如果是— 查找成功
5. 如果不是,将此人的邻居加入队列
6. 回到第二步

from collections import deque
# 以图为模型 建立散列表数据
graph = {}
graph["you"] = ["alice", "bob", "clarie"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["clarie"] = ["thom", "jonny", "doctor"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
graph["doctor"] = []


def search(name):
# 因为搜索
    search_queue = deque()
    search_queue += graph['you']
    searched = []
    while search_queue:
        person = search_queue.popleft()
        if person not in searched:
            if person_is_doctor(person):
                print(person + " is a doctor!")
                break
            else:
                search_queue += graph[person]
                searched.append(person)


def person_is_doctor(name):
    return name[-1] == 'r'

search("you")
题2 来源于leetcode

给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id。

比如,员工1是员工2的领导,员工2是员工3的领导。他们相应的重要度为15, 10, 5。那么员工1的数据结构是[1, 15, [2]],员工2的数据结构是[2, 10, [3]],员工3的数据结构是[3, 5, []]。注意虽然员工3也是员工1的一个下属,但是由于并不是直系下属,因此没有体现在员工1的数据结构中。

现在输入一个公司的所有员工信息,以及单个员工id,返回这个员工和他所有下属的重要度之和。

示例 1:

输入: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1
输出: 11
解释:
员工1自身的重要度是5,他有两个直系下属2和3,而且2和3的重要度均为3。因此员工1的总重要度是 5 + 3 + 3 = 11。
注意:

一个员工最多有一个直系领导,但是可以有多个直系下属
员工数量不超过2000。

解题思路

  1. 和先前一样,为了确保顺序把所有节点放入队列中
  2. 考虑到数据方便操作,把员工的数据存入到散列表中。以id为键
  3. 遍历到对应员工数据后增加重要度值
  4. 按队列顺序遍历subordinates值,把其下属员工继续放入到队列中。继续搜索
"""
# Employee info
class Employee:
    def __init__(self, id: int, importance: int, subordinates: List[int]):
        # It's the unique id of each node.
        # unique id of this employee
        self.id = id
        # the importance value of this employee
        self.importance = importance
        # the id of direct subordinates
        self.subordinates = subordinates
"""
from collections import deque

class Solution:
    def getImportance(self, employees: List['Employee'], id: int) -> int:
        score = 0
        hash_map = dict()
        for emp in employees:
            hash_map[emp.id] = emp

        search_queue = deque()
        search_queue.append(id)
        while search_queue:
            search_id = search_queue.popleft()
            score += hash_map[search_id].importance
            for item in hash_map[search_id].subordinates:
                search_queue.append(item)
        return score