广度优先搜索

广度优先搜索是一种图算法。

图简介

图模拟一组连接。图由节点和边组成。一个节点可能与众多节点直接相连,这些节点被称为邻居。图用于模拟不同的东西时如何相连的。
有向图:如果某个节点有指向他们的箭头,但没有从他们出发指向其他人的箭头,这被称为有向图。
无向图:没有箭头,直接相连的节点互为邻居。

广度优先搜索简介

广度优先搜索是一种用于图的查找算法,可帮助解决两类问题:
第一类问题:从节点A出发,有前往节点B的路径吗?
第二类问题:从节点A出发,前往节点B的哪条路径最短?

队列

广度优先搜索需要按照顺序查找,有一种可实现这种目的的数据结构,队列。队列支持两种操作:入队和出队,且遵循先进先出(First In First Out,FIFO)。

实现图

from collections import deque
import sys

# 在你的朋友和朋友的朋友中寻找芒果经销商(姓名是否以m结尾,如果是,他就是芒果经销商)
# 判断一个人是不是芒果经销商
def person_is_seller(name):
    return name[-1] == 'm'

# 寻找函数
def search(name):
    # 创建一个队列
    search_queue = deque()
    # 将你的邻居都加入到这个搜索队列中
    search_queue += graph[name]
    # 这个数组用于记录检查过的人
    searched = []
    # While循环查找芒果经销商
    while search_queue:  # 只要队列不空
        person = search_queue.popleft()  # 取出其中的第一个人
        if person not in searched:  # 仅当这个人没检查过时才检查
            if person_is_seller(person):  # 检查这个人是否是芒果经销商
                print(person + " is a mango seller!")  # 是芒果经销商,并输出
                sys.exit(0)  # 退出程序
            else:
                search_queue += graph[person]  # 不是芒果经销商,将这个人的朋友都加入搜素队列
                searched.append(person)  # 将这个人标记为检查过
    # 如果到达这里,就说明队列中没人是芒果经销商
    print("No person is a mango seller!")

# 主函数
if __name__ == '__main__':
    # 创建邻居列表
    graph = {}
    graph["you"] = ["alice", "bob", "claire"]
    graph["bob"] = ["anuj", "peggy"]
    graph["alice"] = ["peggy"]
    graph["claire"] = ["thom", "jonny"]
    graph["anuj"] = []
    graph["peggy"] = []
    graph["thom"] = []
    graph["jonny"] = []
    
    search("you")

实现结果

在这里插入图片描述

运行时间

在以上芒果经销商寻找案例中,广度优先搜索的运行时间为O(人数+边数),即O(V+E),其中V为顶点数,E为边数

小结

1.广度优先搜索指出是否有从A到B的途径
2.如果有,广度优先搜索将找出最短路径
3.面临类似于寻找最短路径的问题时,可尝试使用图来建立模型,再使用广度优先搜索来解决问题
4.有向图中的边为箭头,箭头的方向指定了关系的方向,例如,rama->adit表示rama欠adit钱
5.无向图中的边不带箭头,其中的关系是双向的。
6.队列是先进先出(FIFO)的
7.栈是后进先出的(LIFO)的
8.你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列
9.对于检查过的人,务必不要再去检查,否则可能导致无限循环
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值