数据结构与算法 | 深搜(DFS)与广搜(BFS)
深搜(DFS)与广搜(BFS)
在查找二叉树某个节点时,如果把二叉树所有节点理理解为解空间,待找到那个节点理解为满足特定条件的解,对此解答可以抽象描述为: 在解空间中搜索满足特定条件的解,这其实就是搜索算法(Search)的一种描述。当然也有其他描述,比如是“指一类用于在数据集合中查找特定项或解决问题的算法”,又或者是“指通过按照一定规则逐一检查数据,以找到所需的信息或解决特定的问题。”等等。
搜索算法在计算机科学和信息检索中具有广泛的应用,包括搜索引擎、数据库查询、排序、路径规划、机器学习和人工智能等领域。其中最基础之一的搜索算法就是 深度优先搜索(Depth First search,简称 DFS)和广度优先搜索(Breadth First Search,简称 BFS)。
PS:因发明“深度优先搜索算法”,约翰·霍普克洛夫特 与 罗伯特·塔扬在1986年共同获得计算机领域的最高奖图灵奖
在写这两种算法之前,先看几个数据结构。
队列(Queue)、栈(Stack)
排队相信是日常生活中购物时可能遇到的情况,其中最重要的一个原则就是先来的先买。同样的,可以把类似这种规则应用在数据结构上,那么这种数据结构就是队列(Queue):是一种线性数据结构,遵循先进先出(First-In-First-Out,FIFO)的原则。
(PS:什么叫线性数据?指一种数据元素的有序集合,其中元素之间存在线性(有序)关系。)
其两个基本的操作:
- 入队(Enqueue): 向队列的末尾添加一个新元素。这个操作将新元素排队等待被处理。通常,它是队列中元素的最后一个操作。
- 出队(Dequeue): 从队列的前端移除一个元素,并返回它。这个操作模拟了第一个等待的元素被处理的情况。通常,出队操作是队列中元素的第一个操作。
如果把队列遵循的原则进行修改为后进先出,这样就演变出另外一种数据结构 栈(Stack):是一种线性数据结构,它遵循先进后出(Last-In-First-Out,LIFO)的原则。
同样类似队列两个基本操作:
- 入栈(Push): 向栈顶添加一个新元素。
- 出栈(Pop): 从栈顶移除元素。
PS:栈顶(Top)是当前位于栈的顶部的元素,也是栈中唯一一个可见的元素。

LeetCode 20. 有效的括号【简单】
给定一个只包括 '(',')','{','}','','' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。

双端队列(Double-Ended Queue,简称 Deque)
如果要一个数据结构即支持队列的操作也支持栈的操作,双端队列(Double-Ended Queue,简称Deque)是这样一种线性数据结构,它具有队列和栈的特性,允许在队列的两端执行插入和删除操作。双端队列支持元素的快速插入和删除,无论是在队列的前端(头部)还是后端(尾部),因此它被称为"双端",即有两个端点。
双端队列的存储实现上既可以 是链表,也可以是 数组;可以根据实际情况进行选择。
// java 示例代码
Deque<Integer> dequeList = new LinkedList<>();
Deque<Integer> dequeArray = new ArrayDeque<>();

PS:由于双端队列能够覆盖 栈、队列两者的操作,使用Java解决算法题时,如需使用栈(Stack)、队列(Queue)情况 经常都会使用 Deque 来完成。
深度优先搜索(Depth First Search)
深度搜索(Depth-First Search,DFS)中的"深度"指的是在搜索问题的解空间时,算法首先沿着一条路径深入到解空间中,直到达到最深处或者无法再深入为止;然后再回退并继续探索下一个分支。
虽然 在上一篇 二叉树 中没提及这个名称,但其实上篇涉及的几个算法问题解法都是深度搜索;DFS通常使用递归或栈(堆栈)数据结构来实现,在这里不妨再练习一题。
LeetCode 113. 路径总和 II 【中等】
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。

广度优先搜索(Breadth First Search)
广度搜索(Breadth-First Search,BFS)中的"广度"指的是算法在搜索问题的解空间时,从起始点开始逐层地向外扩展,以确保先探索当前层的所有节点,然后再深入到下一层的节点,层层展开。
所谓“层层展开” 例如在二叉树结构中,根节点是第0层,子节点是第1层,孙子节点是第2层,依此类推。BFS通常使用队列数据结构来实现。
LeetCode 515. 在每个树行中找最大值【中等】
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

LeetCode 695. 岛屿的最大面积【中等】
给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。


总结下
- 队列(Queue)、栈(Stack)数据结构开始,引出到 双端队列(Double-Ended Queue);
- 深度搜索(Depth-First Search)的基本应用,通常使用递归或栈(堆栈)数据结构来实现;
- 广度优先搜索(Breadth First Search)的基本应用,通常使用队列数据结构来实现。
数据结构与算法 | 深搜(DFS)与广搜(BFS)的更多相关文章
- 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS
图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其 ...
- 深搜(DFS)广搜(BFS)详解
图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...
- 【数据结构与算法】自己动手实现图的BFS和DFS(附完整源码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/19617187 图的存储结构 本文的重点在于图的深度优先搜索(DFS)和广度优先搜索(BFS ...
- 【数据结构与算法】无向图的结构与遍历 BFS&DFS
1 表示无向图的数据类型 1.1 邻接矩阵 可以使用一个V*V的二维布尔矩阵,当定点v和定点w相连的时候,定义第v行第w列的值为true,否则为false.邻接矩阵不适合定点较多的情况,含有百万的顶点 ...
- HDU-1495 非常可乐 (嵌套结构体-广搜 对比 一般广搜)
题意 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但 ...
- hdu 1026:Ignatius and the Princess I(优先队列 + bfs广搜。ps:广搜AC,深搜超时,求助攻!)
Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- 队列&广搜
搜索里有深搜,又有广搜,而广搜的基础就是队列. 队列是一种特殊的线性表,只能在一段插入,另一端输出.输出的那一端叫做队头,输入的那一端叫队尾.是一种先进先出(FIFO)的数据结构. 正经的队列: 头文 ...
- PTA 7-7 六度空间(广搜)
“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够 ...
- 图的基本操作(基于邻接矩阵):图的构造,深搜(DFS),广搜(BFS)
#include <iostream> #include <stdio.h> #include <cstdlib> #include <cstring> ...
- 什么时候用深搜(dfs)什么时候用广搜(bfs)(转)
1.BFS是用来搜索最短径路的解是比较合适的,比如求最少步数的解,最少交换次数的解,因为BFS搜索过程中遇到的解一定是离根最近的,所以遇到一个解,一定就是最优解,此时搜索算法可以终止.这个时候不适宜使 ...
随机推荐
- 【Linq】Value cannot be null. (Parameter 'row')
报错代码: 原因分析: Linq中左连接后,取值需要处理null值;如下图修改后恢复正常.
- Pycharm里Python运行窗口显示乱码���的解决方法
当你的Python程序运行后,会在运行窗口中显示乱码 ��� 等字样,如下 原因是 Pycharm中默认设置只显示UTF-8编码的格式,需要修改支持显示中文支持. 解决方法: 菜单中选择 File S ...
- 使用Githud 实现分发IPA包遇到的坑
最近要用到测试包分发,首先想到了,蒲公英,但是把包扔上去,扫描下载的时候发现,现在需要用户登录才能下载,弃了. 又跑到fir ,发现还得实名才能用,还得上传各种证件照,而且好像每天只有10个下载量,. ...
- python学习笔记:第九章异常
1.1 异常是什么 python使用异常对象来表示异常状态,并在遇到错误时引发异常.异常对象未被处理,程序将终止并显示一条错误信息. 我们可以通过各种方法引发和捕获错误,并采取对应措施. 1.2 将& ...
- Django+DRF+Vue 网页开发环境安装(windows/Linux)
博客地址:https://www.cnblogs.com/zylyehuo/ 总览 一.安装 Django pip install django==3.2 二.安装 MySQL 驱动程序 pip in ...
- EF6连接oracle
最近项目用到oracle,一直使用sql server,ef很方便连接mssql,但是连接oracle的方法网上很多文章,尝试很多次终于搞定,dbfirst或者codefirst也是可以的. 安装OD ...
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream
伪 分布模式下启动spark报错 从spark1.4以后,所有spark的编译都是没有将hadoop的classpath编译进去的,所以必须在spark-env.sh中指定hadoop中的所有jar包 ...
- Pandas:在DataFrame中添加一行,并设置行索引
解决方案 效果图 参考链接 https://blog.csdn.net/Caiqiudan/article/details/107788525
- pandas对某列数据进行求和
求和的方式很简单,如下所示: number_of_declarations = data[4].sum()//中括号中为要求和的列
- 微服务集成RabbitMq保姆级教程
本文通过简单的示例代码和说明,让读者能够了解微服务如何集成RabbitMq 之前的教程 https://www.cnblogs.com/leafstar/p/17641358.html 在这里我将介绍 ...