python 广度优先算法

文章概述

广度优先搜索算法概述

广度优先搜索算法

广度优先算法是基于树或者图的,当然树也是一种特殊的图,因此我们先简单的介绍下图的相关知识。
介绍:图在计算机学科中是一种重要的数据结构,是树的拓展,由节点和边构成,边可以有权重,也可以有方向,当然,也可以没有。如下简单无向图:



有向图是方向的,用箭头表示:


背景

想要求一个地点到另一个地点,如下图所示,求A到D的最短距离,已知相邻节点之间的距离是相同的。


实现图:

首先用代码表示图,建立数据结构。
那么图如何表示呢,我们知道,图是由节点构成的,每个节点可能有邻居,如A的邻居有B、C,B的邻居是D,D没有邻居,那么我们可以用dict来表示这些关系

graph = {}
graph['A'] = ['B', 'C']

graph['B'] = ['D']
graph['C'] = ['E']

graph['D'] = []
graph['E'] = ['D']

广度优先搜索算法

算法描述:
1.创建一个队列,用于存储要检查的节点
2.从队列首部弹出一个节点
3.判断这个节点是否检查过,若检查过,重复执行步骤2
4.检查这个节点是否目的节点,是的话,完事,否则,将这个节点的邻居加入队列的尾部,重复2,3,4,一直到队列为空

from collections import deque

graph = {}
graph['A'] = ['B', 'C']

graph['B'] = ['D']
graph['C'] = ['E']

graph['D'] = []
graph['E'] = ['D']

def solution(start, end):  #起点和终点
    queue = deque()      #创建一个队列
    queue += graph[start]   #先把起点的邻居加入队列,检查一级关系

    searched = [start]      # 已检查的点,防止造成死循环, 起点不用检查可以加进来

    while queue:  
        address = queue.popleft()  # 弹出节点
        if address not in searched:
            if address == end:
                searched.append(end)  
                return searched  # 返回所有已检查的节点,为后续打印最短路径做准备
            else:
                queue += graph[address]
                searched.append(address)
    return False

searched = solution('A','D')

如果searched 存在,就代表有路径可以让A通往D,其实这个代码实现了一种搜索算法,检索A到D是否存在可达路径,且搜索的时候走的是最短路径。
另外时间复杂度,这个过程我们使用到了队列,将每个节点添加进去的时间都是固定的,为O(1),那么广度优先搜索算法的时间复杂度为O(V+E),其中V为节点数,E为边数。
下面我们想个办法打印出这个最短路径来。

# 求搜索经历的最短路径
#接上面代码 searched 是一个列表
l = []
address = 'D'
l.append(address)
while address != 'A': 
    for i in searched:
        if address in graph[i]:
            l.append(i)
            address = i
            break
print(l[::-1])

我们根据目的节点,反向打印路径中节点,然后取反就是我们的最短路径了['A','B','D']
当然此算法还可以优化,大家可以发动脑筋。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容