深度优先搜索和广度优先搜索

关于搜索&遍历

对于搜索来说,我们绝大多数情况下处理的都是叫 “所谓的暴力搜索” ,或者是说比较简单朴素的搜索,也就是说你在搜索的时候没有任何所谓的智能的情况在里面考虑,很多情况下它做的一件事情就是把所有的结点全部遍历一次,然后找到你要的结果。

基于这样的一个数据结构,如果这个数据结构本身是没有任何特点的,也就是说是一个很普通的树或者很普通的图。那么我们要做的一件事情就是遍历所有的结点。同时保证每个点访问一次且仅访问一次,最后找到结果。

那么我们先把搜索整个先化简情况,我们就收缩到在树的这种情况下来进行搜索。

如果我们要找到我们需要的一个值,在这个树里面我们要怎么做?那么毫无疑问就是从根这边开始先搜左子树,然后再往下一个一个一个一个点走过去,然后走完来之后再走右子树,直到找到我们的点,这就是我们所采用的方式。

再回到我们数据结构定义,它只有左子树和右子树。


我们要实现这样一个遍历或者搜索的话,毫无疑问我们要保证的事情就是

  • 每个结点都要访问一次
  • 每个结点仅仅要访问一次
  • 对于结点访问的顺序不限
    • 深度优先:Depth First Search
    • 广度优先:Breadth First Search

仅访问一次的意思就是代表我们在搜索中,我们不想做过多无用的访问,不然的话我们的访问的效率会非常的慢。

当然的话还可以有其余的搜索,其余的搜索的话就不再是深度优先或者广度优先了,而是按照优先级优先 。当然你也可以随意定义,比如说从中间优先类似于其他的东西,但只不过的话你定义的话要有现实中的场景。所以你可以认为是一般来说就是深度优先、广度优先,另外的话就是优先级优先。按照优先级优先搜索的话,其实更加适用于现实中的很多业务场景,而这样的算法我们一般把它称为启发式搜索,更多应用在深度学习领域。而这种比如说优先级优先的话,在很多时候现在已经应用在各种推荐算法和高级的搜索算法,让你搜出你中间最感兴趣的内容,以及每天打开抖音、快手的话就给你推荐你最感兴趣的内容,其实就是这个原因。

深度优先搜索(DFS)

递归写法

递归的写法,一开始就是递归的终止条件,然后处理当前的层,然后再下转。

  • 那么处理当前层的话就是相当于访问了结点 node,然后把这个结点 node 加到已访问的结点里面去;
  • 那么终止条件的话,就是如果这个结点之前已经访问过了,那就不管了;
  • 那么下转的话,就是走到它的子结点,二叉树来说的话就是左孩子和右孩子,如果是图的话就是连同的相邻结点,如果是多叉树的话这里就是一个children,然后把所有的children的话遍历一次。
  1. 二叉树模版
def dfs(node):   if node in visited:     # already visited     return   visited.add(node)   # process current node   # ... # logic here   dfs(node.left)   dfs(node.right)
  1. 多叉树模版
visited = set()def dfs(node, visited):    if node in visited: # terminator        # already visited     return    visited.add(node)    # process current node here.    ...    for next_node in node.children():      if next_node not in visited:        dfs(next_node, visited)

非递归写法

def DFS(self, tree):  if tree.root is None:     return [] visited, stack = [], [tree.root] while stack:      node = stack.pop()       visited.add(node)     process (node)        nodes = generate_related_nodes(node)     stack.push(nodes) # other processing work   ...

遍历顺序

我们看深度优先搜索或者深度优先遍历的话,它的整个遍历顺序毫无疑问根节点 1 永远最先开始的,接下来往那个分支走其实都一样的,我们简单起见就是从最左边开始走,那么它深度优先的话就会走到底。


参考多叉树模版我们可以在脑子里面或者画一个图把它递归起来的话,把递归的状态树画出来,就是这么一个结构。

  • 就比如说它开始刚进来的话,传的是  root 的话,root 就会先放到 visited 里面,表示 root 已经被 visit,被 visited之后就从 root.childern里面找 next_node,所有它的next_node都没有被访问过的,所以它就会先访问最左边的这个结点,这里注意当它最左边这个结点先拿出来了,判断没有在 visited里面,因为除了 root之外其他结点都没有被 visited过,那么没有的话它就直接调dfsnext_node 就是把最左边结点放进去,再把 visited也一起放进去。
  • 递归调用的一个特殊,它不会等这个循环跑完,它就直接会进到下一层了,也就是当前梦境的话这里写了一层循环,但是在第一层循环的时候,我就要开始下钻到新的一层梦境里面去了。所以在这里的话,

图的遍历顺序


广度优先搜索(BFS)

广度优先遍历它就不再是用递归也不再是用栈了,而是用所谓的队列。你可以把它想象成一个水滴,滴到1这个位置,然后它的水波纹一层一层一层扩散出去就行了。


两者对比


BFS代码模版

# Pythondef BFS(graph, start, end):  visited = set() queue = []   queue.append([start]) while queue:      node = queue.pop()       visited.add(node)     process(node)     nodes = generate_related_nodes(node)     queue.push(nodes) # other processing work   ...

部分图片来源于网络,版权归原作者,侵删。

?点击阅读原文,查看往期内容!

                           快留言?和我互动吧~

八数码深度优先搜索_深度优先搜索和广度优先搜索相关推荐

  1. 深度优先搜索(DFS)与广度优先搜索(BFS)算法详解

    深度优先搜索(DFS)与广度优先搜索(BFS)详解 1.广度优先搜索算法 1.1.前言 和树的遍历类似,图的遍历也是从图中某点出发,然后按照某种方法对图中所有顶点进行访问,且仅访问一次. 但是图的遍历 ...

  2. python扫雷 广度优先_基于邻接矩阵的广度优先搜索遍历(BFS)

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索( ...

  3. 根据邻接表求深度优先搜索和广度优先搜索_深度优先搜索/广度优先搜索与java的实现...

    度:某个顶点的度就是依附于该顶点的边的个数 子图:一幅图中所有边(包含依附边的顶点)的子集 路径:是由边顺序连接的一系列定点组成 环:至少含有一条边且终点和起点相同的路径 连通图:如果图中任一个到另一 ...

  4. 广度优先搜索_深度优先搜索和广度优先搜索[09]

    搜索与遍历 绝大多数搜索的处理叫暴力搜索,或者说比较简单朴素的搜索.如果数据结构本身没有任何特点,很普通的树或者图,我们要做的一件事就是把所有节点都遍历一次. 每个节点都要访问一次 每个节点仅仅要访问 ...

  5. 深度优先搜索(DFS)与广度优先搜索(BFS)详解

    原文来自<挑战程序设计竞赛> 深度优先搜索(DFS)和宽度优先搜索(BFS)都是常见的搜索算法.在学习DFS和BFS之前,我们首先得知道递归函数的概念. 1. 递归函数 通俗地讲,一个函数 ...

  6. 深度优先搜索(DFS)和广度优先搜索(BFS)两种算法c++

    1.BFS和DFS介绍 深度优先搜索(DFS)和广度优先搜索(BFS)是一种用于遍历或搜索树图的一种算法,在这个过程中保证图或数的每个结点被访问且仅被访问一次,再按照每个结点访问的顺序不同分为深搜和广 ...

  7. 深度优先搜索(DFS)和广度优先搜索(BFS)

    深度优先搜索和广度优先搜索,都是图形搜索算法,它两相似,又却不同,在应用上也被用到不同的地方.这里拿一起讨论,方便比较. 先给大家说一下两者大概的区别: 如果搜索是以接近起始状态的程序依次扩展状态的, ...

  8. 深度优先搜索(DFS)与广度优先搜索(BFS)

        深度优先搜索(Depth-First Search)和广度优先搜索(Breadth-First Search)都是对图进行搜索的算法,两者都是从起点开始顺着边搜索,直到找到结果为止,区别在于两 ...

  9. 步步为营(十六)搜索(二)BFS 广度优先搜索

    上一篇讲了DFS,那么与之相应的就是BFS.也就是 宽度优先遍历,又称广度优先搜索算法. 首先,让我们回顾一下什么是"深度": 更学术点的说法,能够看做"单位距离下,离起 ...

最新文章

  1. act转MP3格式工具
  2. 线性表的顺序存储——顺序存储结构的抽象实现
  3. 机房的未来趋势,互联网数据中心(IDC)行业前景图
  4. AndroidStudio_android中实现ImageView的清空操作---Android原生开发工作笔记235
  5. C# winFrom窗体设计问题-部分文件打不开窗体设计器 变成类.cs
  6. 【渝粤题库】广东开放大学 文化产业概论 形成性考核 (2)
  7. 哈理工OJ 1147 重生(水DP)
  8. java扫码枪键盘_JAVA读取USB扫描枪
  9. pythondocx更新目录_使用Python更新MS Word .docx文档的目录(目录)
  10. 路由器的三种配置方式
  11. 飞秋FeiQ可以聊天,但无法传输文件
  12. 买不到的数目(最大不能组合的数)
  13. 互联网产品的运营指标
  14. 【PAT A1094】The Largest Generation
  15. 条码固定资产管理系统的作用,固定资产条码化管理
  16. 基于LLVM编译器的IDA自动结构体分析插件
  17. 当AI对话系统像自动驾驶一样分级,谁能率先跑出L5?
  18. 北京住房公积金转杭州相关信息的整理,个人整理
  19. comp9334辅导 proj2
  20. 设置InternetConnect的httpRequest连接数

热门文章

  1. JSON字符串封装成Bean对象/JSON串反序列化成实体类对象/JSON字符串转换成Java对象
  2. jar/war/ear文件的区别
  3. python提取html正文为txt,python 提取html文本的方法
  4. 修改value_Python | 快速修改或命名N个文件夹名称,你会吗?
  5. 固体加热_干货分享| |固体氧化物燃料电池
  6. html文字列表,文字列表模板
  7. 将html代码转换为dom,将HTML字符转换为DOM节点并动态添加到文档中
  8. wincc历史数据库_WinCC系统的基本功能介绍——自动化工程师必备
  9. python查询sql_Python处理SQL语句(提供SQL查询平台使用)
  10. springmvc怎么设置更改了界面不用重启_Microsoft Visual Studio 2019 更改语言包