在谈广度优先遍历之前,我们需要知道图是什么。

1.图

 图(graph)是表示物件与物件之间关系的数学对象,是图论的基本研究对象,图由节点(node)和边(edge)组成。图分为两种:1.有向图、2.无向图

1.1有向图

有向图就类似于我们去打牌,如果A欠B5元,则有一条线段从A指向B,如果B欠A5元,那么就又有一条线由B指向A,这个5元我们称之为权重(weight)

1.2 无向图

如果有一条线段是由A指向B,并且B指向A。那么这两条线段可以合成一条无箭头的线段在A于B中间。

如果当参加打牌的人数变多时,关系也会变的复杂,如下图所示

上面表示ALEX欠RAMA钱,RAMA欠ADIT钱,TOM欠RAMA和ADIT的钱。

就这么简单!图由节点和边组成。一个节点可能与众多节点直接相连,这些节点被称为邻居。在前面的欠钱图中,Rama是Alex的邻居。Adit不是Alex的邻居,因为他们不直接相连。但Adit既 是Rama的邻居,又是Tom的邻居。

图用于模拟不同的东西是如何相连的。

2.广度优先遍历

广度优先搜索是一种用于图的查找算法,可帮助回答两类问题。

第一类问题:从节点A出发,有前往节点B的路径吗?

第二类问题:从节点A出发,前往节点B的哪条路径最短?

下面我们举个简单的栗子来理解一下广度优先遍历的妙处。

假设你是一个木材厂的老板,你手中有一批上等的好木头,需要寻找一个木材爱好者,把木头卖给他。因此你可以在微信中查找你的朋友是否是木材爱好者或者你可以发朋友圈问朋友他们的朋友中是否有木材爱好者。

为此,你首先在朋友中查找。这种查找很简单。首先,创建一个朋友名单。然后,一次查找名单中的每个人,看看他们是否是木材爱好者。

假设你没有朋友是木材爱好者,那么你就必须在朋友的朋友中查找。检查名单中的每个人时,你都将其朋友加入名单。

这样一来,你不仅在朋友中查找,还在朋友的朋友中查找。别忘了,你的目标是在你的人际关系网中找到一位木材爱好者。因此,如果A不是木材爱好者,就将其朋友也加入到名单中。这意味着你将在她的朋友、朋友的朋友等中查找。使用这种算法将搜遍你的整个人际关系网,直到找到木材爱好者。这就是广度优先搜索算法。

那么python中如何来实现呢?我们需要引入队列(deque)。队列支持两种操作:入队和出队。

如果你将两个元素加入队列,先加入的元素将在后加入的元素之前出队。因此,你可使用队列来表示查找名单!这样,先加入的人将先出队并先被检查。

队列是一种先进先出(First In First Out,FIFO)的数据结构,而栈是一种后进先出(Last In First Out,LIFO)的数据结构。

3.手撕代码

首先,需要使用代码来实现图。图由多个节点组成。每个节点都与邻近节点相连,如果表示类似于“你→Bob”这样的关系呢?它就是字典!

我们可以用字典来将你的所有邻居存入以你为关键字,以邻居为值的字典中。

我们现在来帮木材商(A)查找木材爱好者(I)吧

3.1 创建graph表

我们知道,对于A来说,他有["B","C","F"]三个朋友,B没有朋友,因此为[]。按照这个思路我们就可以构造出如下的一个表

graph = {}
graph["A"] = ["B","C","F"]
graph["B"] = []
graph["C"] = ["E","F","D"]
graph["D"] = ["H","G"]
graph["E"] = ["I"]
graph["F"] = []
graph["G"] = []
graph["H"] = ["I"]
graph["I"] = []

3.2 创建队列

对于队列,我们可以调用python强大的库collections里的deque(另一篇文章有讲该库,可去查看一下)来创建一个双端队列

from collections import deque # 从collections库中导入deque类
search_pepole = deque() # 创建一个队列
search_pepole += graph["A"] # 将A的朋友加入到队列中

3.3创建判断函数

def person_is_seller(person):  # 创建判断函数,查看该人是否是Ireturn person =="I"while search_people: # 如果队列不为空    person = search_people.popleft() # 取出当前队列的第一个人if person_is_seller(person): # 检查这个人是否是I        print(person +" is a love tree'people!") # 是Ibreakelse:        search_people += graph[person] # 如果不是,则把这个人的朋友都加入到队列中

3.4 检查代码

回去看一下代码,我们会发现,如果B是C的朋友,C是D的朋友,D又是B的朋友,那么我们就会将整个循环进入一个无限的循环之中,我们可以添加一个列表,用来存储已经被查找过的用户

def search(name):
    search_people = deque() # 创建一个队列
    search_people += graph[name] # 将name的朋友加入到队列中
    searched = []while search_people: # 如果队列不为空
        person = search_people.popleft() # 取出当前队列的第一个人
        ifnot person in searched: # 如果这个人没有被查找过if person_is_seller(person): # 检查这个人是否是I
                print(person +" is a love tree'people!") # 是Ibreakelse:
                search_people += graph[person] # 如果不是,则把这个人的朋友都加入到队列中
    returnFalse

4.完整代码

# -*- coding: utf-8 -*-from collections import deque # 从collections库中导入deque类
graph = {}
graph["A"] = ["B", "C", "F"]
graph["B"] = []
graph["C"] = ["E", "F", "D"]
graph["D"] = ["H", "G"]
graph["E"] = ["I"]
graph["F"] = []
graph["G"] = []
graph["H"] = ["I"]
graph["I"] = []def person_is_seller(person):  # 创建判断函数,查看该人是否是Ireturn person =="I"def search(name):
    search_people = deque() # 创建一个队列
    search_people += graph[name] # 将name的朋友加入到队列中
    searched = []while search_people: # 如果队列不为空
        person = search_people.popleft() # 取出当前队列的第一个人
        ifnot person in searched: # 如果这个人没有被查找过if person_is_seller(person): # 检查这个人是否是I
                print(person +" is a love tree'people!") # 是Ibreakelse:
                search_people += graph[person] # 如果不是,则把这个人的朋友都加入到队列张红
    returnFalse
search("A")

python 遍历_Python手撕广度优先遍历相关推荐

  1. python 遍历_python实现图广度优先遍历、深度优先遍历

    一.广度优先遍历-BFS 顾名思义,BFS总是先访问完同一层的结点,然后才继续访问下一层结点,它最有用的性质是可以遍历一次就生成中心结点到所遍历结点的最短路径,这一点在求无权图的最短路径时非常有用.广 ...

  2. 数据结构(廿六) -- C语言版 -- 图 - 图的遍历 -- 邻接表 - 深度/广度优先遍历/搜索(DFS、BFS)

    内容预览 零.读前说明 一.深度优先遍历 1.1.深度优先的遍历过程 1.2.深度优先的遍历实现代码 二.广度优先遍历 2.1.广度优先的遍历过程 2.2.广度优先的遍历实现代码 三.源码测试效果 3 ...

  3. 数据结构之栈的应用:树的层次遍历、图的广度优先遍历、OS的FCFS策略

    栈的应用:树的层次遍历.图的广度优先遍历.OS的FCFS策略 树的层次遍历: 图的广度优先遍历 OS的FCFS策略: 树的层次遍历: 算法思想: 1.先遍历头节点1,头节点1入队 2.在遍历头节点的孩 ...

  4. python 深度优先遍历_Python算法-二叉树深度优先遍历

    二叉树 组成: 1.根节点BinaryTree:root 2.每一个节点,都有左子节点和右子节点(可以为空)TreeNode:value.left.right 二叉树的遍历: 遍历二叉树:深度优先遍历 ...

  5. 三十二、图的创建深度优先遍历(DFS)广度优先遍历(BFS)

    一.图的基本介绍 为什么要有图 前面我们学了线性表和树 线性表局限于一个直接前驱和一个直接后继的关系 树也只能有一个直接前驱也就是父节点 当我们需要表示多对多的关系时, 这里我们就用到了图. 图的举例 ...

  6. java二叉树的深度优先遍历_二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式...

    1 packageSolution;2 3 importjava.util.LinkedList;4 importjava.util.Queue;5 importjava.util.Stack;6 7 ...

  7. c++ stack 遍历_python实现二叉树的遍历以及其他基本操作

    主要内容: 二叉树遍历(先序.中序.后序.宽度优先遍历)的迭代实现和递归实现: 二叉树的深度,二叉树到叶子节点的所有路径. 首先,先定义二叉树类(python3),代码如下: class 内容1:二叉 ...

  8. python文件夹遍历_Python练习6-文件遍历

    第 0005 题:你有一个目录,装了很多照片,把它们的尺寸变成都不大于 iPhone5 分辨率的大小. 这道题主要用到文件遍历和图片处理的知识,由于图片处理之前已经学过了,所以新的知识点主要是文件遍历 ...

  9. python中字典的循环遍历_python中字典如何遍历循环

    python中字典如何遍历循环 发布时间:2020-09-24 14:16:07 来源:亿速云 阅读:64 作者:Leah 这篇文章将为大家详细讲解有关python中字典如何遍历循环,文章内容质量较高 ...

最新文章

  1. [UWP]在应用开发中安全使用文件资源
  2. python 操作fit文件图像
  3. SAP MM 移动类型-入门篇
  4. docker images 详解
  5. 入行IT,为什么建议你学Java?
  6. Python之面向对象四
  7. 关于android的外文论文,关于android的外文文献.doc
  8. 《转》Ubuntu 12.04常用的快捷键
  9. LeetCode 1332. 删除回文子序列
  10. (Kali)BackTrack-linux安全***测试系统盘
  11. String(min)
  12. [BZOJ1001]: [BeiJing2006]狼抓兔子
  13. MFC工作笔记0010---PeekMessage 详解
  14. 关于Exchange Server 2010(WEB浏览证书)证书问题
  15. 对象的生命周期回顾篇
  16. js继承的几种方式,圣杯模式
  17. HI3519移植samba服务器
  18. java时间为什么只显示到日_java-为什么此日期未在格林尼治标准时间显示?
  19. Nginx代理规则总结
  20. 微信开发中两种access_token的区别

热门文章

  1. [云炬创业基础笔记]第七张创业团队测试8
  2. USTC English Club Note20171020(3)
  3. [MATLAB学习笔记] global声明全部变量
  4. 台湾大学林轩田机器学习技法课程学习笔记16(完结) -- Finale
  5. linux格式化该新添加的分区,Linux下添加新硬盘及分区格式化要点
  6. python def method_给python类动态添加方法(method)
  7. Delphi中的TreeView
  8. 保存delphi中的library path
  9. Delphi中比较两个对象是否一致及地址是否相同
  10. 当map遇上range