【数据结构与算法】数据结构算法--广度优先算法搜索(Python实现)



广度优先搜索(breadth - firsr search ,BFS)

参考书籍:算法图解
在这里插入图片描述

最短距离:

广度优先搜索让你能找够两样东西之间的最短距离,但是最短距离的含义有很多 :
- 编写象棋计算算法,计算最少走多少步就可以获胜。
- 编写拼写检查,计算最少编辑多少个地方就可以将错拼单词改写成正确的单词
- 根据你的人际关系网络找到最有可能的单身异性

  • 图是由结点和边构成,一个结点可能和众多的节点直接相连,这些结点被称为邻居
  • 图用于模拟不同东西如何相互连接

广度优先搜索:

  • 广度优先搜索是一种用于图的查找算法:
    针对两类问题:
    1. 从节点A出发,有前往结点B的路径吗?
    2. 从节点A出发,前往结点B那条路径最短?

广度优先搜索的解决思路(一)含有路径:

假如你正在寻找一个富婆当女朋友,需要寻找一个单身富婆的联系方式,为此你可以在你的朋友圈中寻找:
1. 首先你先创建一个朋友名单
2. 依次检查出名单每个人,看是否单身有钱且异性
3. 假若没有朋友是符合富婆判定条件,则必须在你朋友中寻找
4. 将朋友的朋友加入名单
5. 依次检查出朋友名单每个人,看是否单身有钱且异性
这种算法将搜遍你整个人际关系网络,这就是广度优先算法

广度优先搜索的解决思路(二)最短路径:

那么第二类问题:谁是关系最近的富婆,我们把朋友看作一层关系,朋友的朋友就是二层关系
我们假设 A1 A2 A3 是一度关系(朋友) B1 B2 B3 是二度关系 (朋友的朋友):

  • 那么一度关系胜过二度关系,二度关系胜过三度关系
  • 先从一度关系名单寻找,再从二度关系名单寻找
  • 按照这种关系寻找,只有给每个名单添加一个顺序,有一种可以实现这种数据结构 那就是是队列

队列:

队列是一种先进先出的数据结构(Fist In Fist Out) FIFO ,与栈后进后出相对LIFO(Last IN)

散列表:

散列表可以将键映射到值,这里我们将节点映射到其他所有邻居
表示这种映射关系的Python代码如下

graph = {}
graph["you"]=["A1","A2","A3"]

在这里插入图片描述

  • 此时你被映射到了一个数组里 包含了“你”的和你的所有邻居(“A1 A2 A3”)
    若是更加复杂的关系
graph = {}
graph["you"]=["A1","A2","A3"]
graph["A1"]=["B1","B2","B3"]
graph["B2"]=["C3"]
graph["C3"]=["A2"]
graph["C3"]=["D4"]
graph["B3"]=["D4"]

在这里插入图片描述

散列表顺序:

  • 键-值的添加顺序先后顺序本来就不重要 散列表是无序的,因此添加键-值对的,顺序无关紧要。

有向图和无向图:

如果图形中的所有边都是无向的,那么我们说这个图是无向图。同样,一个有方向的图
也称为有向图,其所有边都是有向的。一个图若同时有有方向的边和无方向的边,则通常称为混合图(我们此时的朋友关系基本指无向图(互有关系))
在这里插入图片描述

实现算法:

创建队列

首先创建一个队列,在Python中,可以使用函数deque来创建一个双端队列

form collections import deque  
search_queue = deque()   # 创建一个队列
search_queue += graph["you"] #将你的邻居加入这个搜索路径

此时别忘了,graphp[“you”]是一个数组,其中包括你所有朋友A1 A2 A3都会加入搜索列表中

遍历队列

while search_queue:  # 只要队列不为空
    person =search_queue.popleft() # 就取出其中的第一个人
    if person_is_seller(person): # 检查这个人是不是富婆
        print person + " is a mango seller!" # 是富婆
        return True
    else:
        search_queue += graph[person]  #不是富婆,将所有朋友都加入搜索的序列
    return False  # 队列中没人是富婆

查找代码:

这个代码搜寻的通过查找有没有 名称‘8’ 来发现富婆

def person_is_seller(name):
    return name[-1]='8'

注意事项:

这个代码会不断执行,直到满足了以下两个条件:

  • 找到了富婆
  • 队列变成空的,这·一位着人际关系网中没又富婆

这样便会衍生出一个问题:

  • B2 和C3 以及A1都是好朋友,在遍历检查中,A1检查了一遍,C3又检查了一便,因此算法做了无用功

  • 假如你用这张图来表示:则会陷入了无限的循环之中:
    在这里插入图片描述

  • 为此我们将设置一个列表 来记录检查过的人


考虑这一点之后,完整的广度优先搜索算法如下:

  from collections import  deque
def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []  # 这个数组用来记录被检查过的人
    while search_queue:
        person = search_queue.popleft()
        if person not in searched:
            if person_is_seller(person):
                print (person + "is a fupo!")
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
            return False

def person_is_seller(name):
    return name[-1] ==  '8'

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法Python) 一、引入概念 1-01算法引入 1-02 时间复杂度与大O表示法 1-03-最坏时间复杂度与计算规则 1-04-常见时间复杂度与大小关系 1-05-代码执行时间测量模块 1-06-Python列表类型不同操作的时间效率 1-07-Python列表与字典操作的时间复杂度 1-08-数据结构引入 二、顺序表 2-01 内存、类型本质、连续存储 recv 2-02 基本顺序表与元素外围顺序表 recv 2-03 顺序表的一体式结构与分离式结构 recv 2-04 顺序表数据区替换与扩充 recv 三、栈 3-01 栈与队列的概念 3-02 栈的实现 3-03 队列与双端队列的实现 四、链表 4-01 链表的提出 4-02 单链表的ADT模型 4-03 Python中变量标识的本质 4-04 单链表及结点的定义代码 4-05 单链表的判空、长度、遍历与尾部添加结点的代码实现 4-06 单链表尾部添加和在指定位置添加 4-07 单链表查找和删除元素 4-08 单链表与顺序表的对比 4-09 单向循环链表遍历和求长度 4-10 单向循环链表添加元素 4-11 单向循环链表删除元素 4-12 单向循环链表删除元素复习及链表扩展 4-13 双向链表及添加元素 4-14 双向链表删除元素 五、排序与搜索 5-01 排序算法的稳定性 5-02 冒泡排序及实现 5-03 选择排序算法实现 5-04 插入算法 5-05 插入排序 5-06 插入排序2 5-07 希尔排序 5-08 希尔排序实现 5-09 快速排序 5-10 快速排序实现1 (1) 5-10 快速排序实现1 5-11 快速排序实现2 5-12 归并排序 5-13 归并排序 代码执行流程 5-14 归并排序时间复杂度及排序算法复杂度对比 5-15 二分查找 5-16 二分查找时间复杂度 六、树和树的算法 6-01 树的概念 6-02 二叉树的概念 6-03 二叉树的广度优先遍历 6-04 二叉树的实现 6-05 二叉树的先序、中序、后序遍历 6-06 二叉树由遍历确定一棵树 ———————————————— 版权声明:本文为CSDN博主「dwf1354046363」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/dwf1354046363/article/details/119832814

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值