图是一种善于处理关系型数据的数据结构,使用它可以很轻松地表示数据之间是如何关联的

图的实现形式有很多,最简单的方法之一就是用散列表

背景

图有两种经典的遍历方式:广度优先搜索和深度优先搜索。两者是相似的。

实现

1广度优先搜索算法需要用队列来记录后续要处理哪些顶点。

2该队列最初只含有起步的顶点

3处理顶点。我们将其移出队列,标为“已访问”,并记为当前顶点

class Bfs:
def __init__(self,from_v,json):
# 最初的顶点
self.from_v = from_v
# 已访问
self.visitList = [self.from_v]
# 需要一个队列来记录后续需要处理哪些顶点
self.vertexQ = queue.Queue()
self.json = json

核心步骤

(1) 找出当前顶点的所有邻接点。如果有哪个是没访问过的,就把它标为“已访问”,并且将它入队。(尽管该顶点并未作为“当前顶点”被访问过。)

(2) 如果当前顶点没有未访问的邻接点,且队列不为空,那就再从队列中移出一个顶点作为当前顶点。

(3) 如果当前顶点没有未访问的邻接点,且队列里也没有其他顶点,那么算法完成。

图解

1首先A会作为顶点,A被访问

2再去寻找A领接点B、D,依次加入队列

3A所有领接点都访问完成,开始访问B的领接点

4知道队列为空,算法结束

代码展示

class Bfs:
def __init__(self,from_v,json):
# 最初的顶点
self.from_v = from_v
# 已访问
self.visitList = [self.from_v]
# 需要一个队列来记录后续需要处理哪些顶点
self.vertexQ = queue.Queue()
self.json = json def find_neighbor(self,currentVertex):
#寻找领接点
for neighbor in self.json[currentVertex]:
if neighbor not in self.visitList:
self.visitList.append(neighbor)
self.vertexQ.put(neighbor) def checkTOV(self,currentVertex,to_v):
#检测要寻找的值(to_v)是否已经在当前currentVertex中
return to_v in self.json[currentVertex] def searchV(self,to_v):
reverseList = [self.from_v]
self.find_neighbor(self.from_v)
while not self.vertexQ.empty():
currentVertex = self.vertexQ.get()
reverseList.append(currentVertex)
tmp_path = Reverse(currentVertex,self.json).reverseOrder(reverseList,currentVertex)
if currentVertex == to_v:
print(tmp_path)
else:
self.find_neighbor(currentVertex)
if self.checkTOV(currentVertex,to_v):
tmp_path.append(to_v)
print(tmp_path)

此外我们额外写了一个向上反向找寻路径的工具类(主要代码写好,不想动原来的结构了)

class Reverse:
def __init__(self,from_v,json):
self.from_v = from_v
self.json = json
def reverseOrder(self,reverseList:list,current_v):
indexReverseList = self.indexReverseList(reverseList)
res = [self.from_v]
tmp = current_v
while len(reverseList) > 0 :
# for _key in self.value2Key(current_v):
_key = self.value2Key(reverseList,tmp)
res.append(_key)
reverseList = reverseList[:indexReverseList[_key]]
tmp = _key
return res[::-1] def value2Key(self,reverseList:list,current_v):
#根据值找json中的key
#这里我们每次都只取离我们最近的一个key
indexReverseList = self.indexReverseList(reverseList)
tmp = -1
for _key, _value in self.json.items():
if current_v in _value and _key in reverseList and (index := indexReverseList[_key]) > tmp:
tmp = index
return reverseList[tmp] def indexReverseList(self,reverseList:list):
return {value: index for index, value in enumerate(reverseList)}

运行结果

json = {"A":["B","D"],"B":["C"],"C":["E","D"],"D":["E"],"E":["B"]}
#从A出发找B
b=Bfs("A",json)
b.searchV("B")

用Python实现广度优先搜索的更多相关文章

  1. python实现广度优先搜索和深度优先搜索

    图的概念 图表示的是多点之间的连接关系,由节点和边组成.类型分为有向图,无向图,加权图等,任何问题只要能抽象为图,那么就可以应用相应的图算法. 用字典来表示图 这里我们以有向图举例,有向图的邻居节点是 ...

  2. python实现广度优先搜索

    from collections import deque #解决从你的人际关系网中找到芒果销售商的问题#使用字典表示映射关系graph = {} graph["you"] = [ ...

  3. python 实现图的深度优先和广度优先搜索

    在介绍 python 实现图的深度优先和广度优先搜索前,我们先来了解下什么是"图". 1 一些定义 顶点 顶点(也称为"节点")是图的基本部分.它可以有一个名称 ...

  4. 常用算法2 - 广度优先搜索 & 深度优先搜索 (python实现)

    1. 图 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 简单点的说:图由节点和边组成.一 ...

  5. python 递归深度优先搜索与广度优先搜索算法模拟实现

    一.递归原理小案例分析 (1)# 概述 递归:即一个函数调用了自身,即实现了递归 凡是循环能做到的事,递归一般都能做到! (2)# 写递归的过程 1.写出临界条件2.找出这一次和上一次关系3.假设当前 ...

  6. 【数据结构与算法Python版学习笔记】图——词梯问题 广度优先搜索 BFS

    词梯Word Ladder问题 要求是相邻两个单词之间差异只能是1个字母,如FOOL变SAGE: FOOL >> POOL >> POLL >> POLE > ...

  7. 广度优先搜索(BFS)解题总结

    定义 广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法. 简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点. 如果所有节点均被访问,则算法中止. B ...

  8. 图的广度优先搜索(BFS)

    把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...

  9. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

随机推荐

  1. JS:构造函数

    定义:在JavaScript中,用new关键字来调用的函数,称为构造函数,构造函数首字母一般大写. 理解: 构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象. 创建对象, ...

  2. .Net Core 企业微信更新模版卡片消息

    1.搭建回调服务器 可参考:https://www.cnblogs.com/zspwf/p/16381643.html进行搭建 2.编写代码 2.1接口定义 应用可以发送模板卡片消息,发送之后可再通过 ...

  3. node环境下怎样优化引入多文件(实现自动化)

    const mocks = [];function getJsonFiles(jsonPath) {function findJsonFile(path) {let files = fs.readdi ...

  4. SAP - 拆包,组件入库

    场景: 一个成品商品,例如汽车,有很多零部件:车轮,框架,发动机等.以整体形式发货过账,在遇到质量问题客户退货情况,需要把汽车拆开,然后零部件退回到库(按照BOM结构拆卸). MB1A/MIGO:发货 ...

  5. SAP 下拉框(选择屏幕)

    一.选择屏幕下拉框. DATA: g_vrmid TYPE vrm_id, "id of value set gt_vlist TYPE vrm_values, "internal ...

  6. Markdown第一次学习

    # # Markdown学习 一级标题: #空格+标题名称+回车得到一级标题 ## 二级标题 一级标题方法中变成两个##号 ### 三级标题 变成三个###号,以此类推,最多到六级标题 ## 字体 h ...

  7. Redis主从复制+Keepalived+VIP漂移实现HA高可用技术之详细教程

    1.大家可以先看我的单台Redis安装教程,链接在此点击Redis在CentOS for LInux上安装详细教程 2.第一台redis配置,是正常配置.作为MASTER主服务器,第二台redis的配 ...

  8. Tapdata 与阿里云 PolarDB 开源数据库社区联合共建开放数据技术生态

      近日,阿里云 PolarDB 开源数据库社区宣布将与 Tapdata 联合共建开放数据技术生态.在此之际,一直专注实时数据服务平台的 Tapdata ,也宣布开源其数据源开发框架--PDK(Plu ...

  9. Thread类的常用方法_sleep和创建多线程程序的第二种方式_实现Runnable接口

    sleep方法是在Thread类中的一个静态方法,当一个线程调用了sleep方法,被调用的那个线程就会暂时的让出指定时间的CPU执行权,在这段时间也不会参与CPU的调度,当时间到了之后,就会重新回到就 ...

  10. kubernetes 调度

    pod 分配给特定的node节点 目的:在一般业务场景,有些pod需要运行在特定的物理节点上,可以通过kubernetes的nodeSelector.nodeName安排pod到指定的节点上运行. # ...