数据结构python:1.广度优先搜索BFS&深度优先搜索DFS&节点间求最短路径、距离

本文介绍了图的遍历算法——BFS(广度优先搜索)和DFS(深度优先搜索),通过Python代码展示了它们的基本实现。并探讨了如何利用优先队列求解图中两点间的最短路径,详细解释了优先队列的工作原理和在求解过程中如何更新节点距离及路径。
摘要由CSDN通过智能技术生成

 输入的图如下所示:

 用python字典将每个节点,及相连节点重构:

graph = {
    'A':['B','C'],
    'B':['A','C','D'],
    'C':['A','B','D'],
    'D':['B','C','E','F'],
    'E':['C','D'],
    'F':['D']
}

BFS,DFS大致思路一致,唯一不同点在于:BFS使用“队列”实现;DFS使用“”实现。即,代码方面,BFS中的queue使用pop(0)实现,DFS中的queue使用pop(-1)或pop()实现

BFS代码:

graph = {
    'A':['B','C'],
    'B':['A','C','D'],
    'C':['A','B','D'],
    'D':['B','C','E','F'],
    'E':['C','D'],
    'F':['D']
}

def BFS(graph , s): #graph:图 , s:输入一个图的起始节点
    queue = []  # 创建一个队列
    queue.append(s)  # 将起始节点放入队列中
    seen = set()   # 用来存储所有已经经过的节点
    seen.add(s)
    while queue:
        vertex = queue.pop(0)  # 弹出队列最前面的一个节点
        nodes = graph[vertex]  # 找到vertex的相邻的节点
        for w in nodes:  # 对于所有节点
            if w not in seen:
                queue.append(w)
                seen.add(w)
        print(vertex)

测试:输入节点‘A’:

BFS(graph , 'A')
------------- 输出-------------------
A
B
C
D
E
F

输入节点‘E':

BFS(graph , 'E')
--------------输出-----------
E
C
D
A
B
F

-----------------------------------------------------------------------------------------------------------------------------

DFS:由于跟BFS不同处在于,BFS使用的队列;DFS使用的栈。上述代码,可以直接修改。

DFS代码:

graph = {
    'A':['B','C'],
    'B':['A','C','D'],
    'C':['A','B','D'],
    'D':['B','C','E','F'],
    'E':['C','D'],
    'F':['D']
}

def DFS(graph , s): #graph:图 , s:输入一个图的起始节点
    stack= []  # 创建一个栈
    stack.append(s)  # 将起始节点放入队列中
    seen = set()   # 用来存储所有已经经过的节点
    seen.add(s)
    while stack:
        vertex = stack.pop()  # 弹出栈最上面的节点
        nodes = graph[vertex]  # 找到vertex的相邻的节点
        for w in nodes:  # 对于所有节点
            if w not in seen:
                stack.append(w)
                seen.add(w)
        print(vertex)

只需要讲pop函数改成pop(-1)或者pop()即可。

测试DFS:

DFS(graph , 'A')
---------------输出-------------
A
C
D
F
E
B
DFS(graph , 'E')
--------------输出-------------
E
D
F
B
A
C

------------------------------------------------------------------------------------------------------------------------------

扩展:从图的一个节点走到另一个节点的,最短距离,最短路径

 若,每个边表示了不同的长度,即:A-B的长度为5。利用BFS,求解,从一个节点到另一个节点的最短距离。

分析:

例如,求A到D的最短距离,当没有长度表示时,A到D的最短距离为2,即A-B-D,A-C-D.

但加上长度后,距离就不同了。

 BFS使用的队列,从A出发,A与B,C相邻1条边,A与D,E距离两条边。

 故,求解路径最短问题,要用到“优先队列”(priority queue)。

优先队列:

例如,有A,C,D分别入队,其中A-1(序号),C-5,D-3。如下图,A,C,D入队

 A入队:

 C入队:

 D入队:

 当D入队后,由于D的序号为3,C的序号为5,故D要排到C前面。

 回到求解最短距离的问题:

 例如,以A为起始点,依次将各节点放入优先队列中。

 A到A的距离为0,故A,0。B到A的距离为5,故B,5。再调整位置:调整过程为内部调整。

再弹出C-1,此时外面的点为A,0-C,1。此时由C到B依然有连线,故再插入队列一个B,3(3表示,从A出发,经过C,再到B,即1+2=3),由优先队列特性可得:

构建列表,表示该节点,从哪个节点而来:

 其中,B是由C而来,因为优先队列,先弹出的C,再是B。

此时寻找B的下一个节点,有A,C,D,由于A,C已经弹出,故只有D。且,距离为B中距离的3,加上B-D距离1,故优先队列插入D,4:

 再调整位置:

同时,parent也做调整:

继续寻找与D相连的节点:

 排除BC。 同时算出到E,F的距离分别是7,10.

队列插入E,F:

调整:

并修改parent:

下一步优先队列弹出B,D,由于B,D已经做过,故丢弃:

继续弹出E,7:

接着弹出E,9

 E,9丢弃。最后拿出F

 

注意:F是跟D相连。 

 找到从A到F的最短距离:

在parent中一步一步寻找。

A-C-B-D-F

代码:

import headpq

 使用headpq库。

数字代表该节点与key节点之间的距离。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值