广度优先搜索

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的联系方式。

MA, B, C
AM, N, G
BM, N
CM, 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'] = []

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

M
A
B
C
N
G
P
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前面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值