非常易于理解的超简单图广度优先遍历、深度优先遍历算法python实现

非常易于理解的超简单图广度优先遍历、深度优先遍历算法python实现#!/usr/bin/envpython#coding=utf-8importnetworkxasnximportQueuedefbfs(adj,start):visited=set()q=Queue.Queue()q.put(start)whilenotq.empty():u=q.get()print(…

大家好,又见面了,我是你们的朋友全栈君。

广度优先遍历(BFS)

顾名思义,BFS总是先访问完同一层的结点,然后才继续访问下一层结点,它最有用的性质是可以遍历一次就生成中心结点到所遍历结点的最短路径,这一点在求无权图的最短路径时非常有用。广度优先遍历的核心思想非常简单,用python实现起来也就十来行代码。下面就是超精简的实现,用来理解核心思想足够了:

import Queue

def bfs(adj, start):
    visited = set()
    q = Queue.Queue()
    q.put(start)
    while not q.empty():
        u = q.get()
        print(u)
        for v in adj.get(u, []):
            if v not in visited:
                visited.add(v)
                q.put(v)


graph = {1: [4, 2], 2: [3, 4], 3: [4], 4: [5]}
bfs(graph, 1)

解释一下代码:

1、创建一个队列,遍历的起始点放入队列

2、从队列中取出一个元素,打印它,并将其未访问过的子结点放到队列中

3、重复2,直至队列空

时间复杂度:基本与图的规模成线性关系了,比起图的其它算法动不动就O(n^2)的复杂度它算是相当良心了

空间复杂度:我们看到程序中使用了一个队列,这个队列会在保存一层的结点,当图规模很大时占用内存还是相当可观的了,所以一般会加上一些条件,比如遍历到第N层就停止

关于图的理解的一个技巧

上面提到,BFS遍历会由近及远,同一层会先遍历完。这里随便提一个关于图的展示问题,或者说当你拿到一个图,当你要对它进行分析时,这个图在你的脑海里会一个什么形态呢?比较一下下面两种形态,你觉得哪一种更加清晰?

非常易于理解的超简单图广度优先遍历、深度优先遍历算法python实现

非常易于理解的超简单图广度优先遍历、深度优先遍历算法python实现

其实你仔细看,左右两张图其实数据是一样的,只是布局不一样罢了,上面的图使用了一种无规律凌乱的布局,而下面假设出了一个中心点,将与它直接相连的结点放在第一层上,与它距离为2的结点放在第二层了,这样会有什么好处呢?好处就是这样布局后边只会在相邻层或者同一层间的结点间相连,这样就不会出现很长或者交叉的边了,整个图会感觉有序得多,在思考图的一些性质的时候也会清晰得多。

回过头来,这种布局不就是BFS形成的吗。

深度优先遍历(DFS)

深度优先遍历算法(DFS),相比于BFS,只需要将队列改成LifoQueue(其实也就是栈)就可以了:

# encoding=utf-8
import Queue

def bfs(adj, start):
    visited = set()
    q = Queue.LifoQueue() # 与BFS相比,只用改这一行代码
    q.put(start)
    while not q.empty():
        u = q.get()
        print(u)
        for v in adj.get(u, []):
            if v not in visited:
                visited.add(v)
                q.put(v)


graph = {1: [4, 2], 2: [3, 4], 3: [4], 4: [5]}
bfs(graph, 1)

解释一下代码(LIFO队列就是栈,下面文字改用栈来描述):

1、创建一个栈,将遍历的起始点放入栈

2、从栈弹出一个元素,打印它,并将其未访问过的子结点压栈

3、重复2,直至栈空

不同时BFS时用的一般队列Queue,DFS时使用了和栈等效的LIFO队列,也就是后加入的会先拿出,所以子结点会优先被访问到。

时间复杂度:与图的规模成线性关系了,为O(n)。

空间复杂度:栈会保存从根到叶子路径上的结点,及他们子结点,所以空间复杂度还是比较小的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140834.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • navicat prem激活码(注册激活)

    (navicat prem激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/ide…

    2022年3月27日
    82
  • resharper 激活码【2021免费激活】

    (resharper 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月30日
    1.1K
  • rsync服务的三种模式测试[通俗易懂]

    rsync服务的三种模式测试[通俗易懂]目录1什么是rsync1.1rsync简介rsync特性1.3rsync的企业工作场景说明2rsync三种模式:2.1rsync常用参数选项2.2rsync本地模式2.3rsyncshell模式2.4rsyncdaemon模式3rsync服务故障模拟4rsync多模块实战5rsync排除及无差异同步实战6rsync优缺点6….

    2022年10月13日
    3
  • 玩转SpringSession,重要知识点全面剖析!

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:怀瑾握瑜 www.cnblogs.com/lxyit/p/9672097.html 前言 在开始spring-…

    2021年6月26日
    88
  • Java是什么?Java到底能干嘛?

    Java是什么?Java到底能干嘛?我刚开始学习Java的时候,很长一段时间都有这么个疑惑?Java到底是啥?它能干什么?自己也看过不少的课程和书,大部分都是从Java的发展史开始讲,总之就是那些什么Jav…

    2022年7月7日
    18
  • 离散数学总复习精华版(最全 最简单易懂)已完结

    离散数学总复习精华版(最全 最简单易懂)已完结离散数学期末总复习精华版P1命题逻辑的基本概念虽然是不确定但是可以是命题就是无法判断真假优先级P2命题逻辑等值演算第一种方法:真值表求第二种用等值演算求P3命题逻辑推理理论下面给出例题后面的可以写成前提引入T12下面给出反证法附加前提证明:…………

    2022年6月18日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号