bfs和dfs辨析—基础复习(从stack和queue的角度来理解区别,加深理解,不再模糊)
参考:
https://www.cnblogs.com/Tovi/articles/6194815.html
https://blog.csdn.net/dangzhangjing97/article/details/81477192
一般来说,dfs总是先学,然后再学bfs,因为dfs就是一个简单的递归思想,理解起来比较简单,思维过程如下,
dfs(要搜的点){
将该点标记为已搜过
if(终止条件){
如果找存在路径,就退出
如果找最短路径,就比较这个与最小值,回去接着找
}
else{
case1{
目标值变化//可以是n层循环
dfs(case1);
目标值恢复到原来
}
case2 ...
case3 ...
}
}
用stack来理解就是,每次”返回“的方式都是弹出之前那一个,即由ann->弹出,下一个是ann-1,再看看ann-1指向的地方有没有没到的
总共三个过程:
- 某节点到底了,还没找到满足条件的
- 弹出 stack ,销毁这个分支, 返回到上一个
- 检查当前往下的另一个方向。有,则再往下另一个分支,压入stack。没有,就继续 "弹出"当前stack
但是学完dfs之后,再学习bfs的时候总是把这两个搞混, 尤其是它加入了queue这个结构来实现"返回",
而且之前一直搞不懂, bfs虽然是"按层"搜索,但是也有 "返回" 的过程, 可是, dfs也有返回过程啊,这个"返回"和dfs的到底有甚区别??!!
后来又重新看了一些stack和queue的辨析(文章开头的链接),才慢慢理解到:
虽然 bfs 也有“返回”,但是,它的返回,其实是在 an这一层已经完全遍历完了之后,才考虑“返回”还是继续 “往下”,
它是已经把当前这一层的情况都记录下来了,才考虑后续的操作,所以常常说bfs耗空间,因为它要记录!!!它的“返回”只有两个过程!
- 某节点到底了,还没找到满足条件的
- 直接横向看,检查,当前这一层是否还有没有遍历完的“邻支”,有,则再往旁边另一个分支。没有,就 "返回"
总结就是,dfs返回 ,先要找到“上家” ,再看有没有分支,而 bfs,可以直接找“邻居”,比较粗暴,直接横着来,
那它凭什么这么做呢?因为它用的是 queue ,这样来理解就是,bfs 总是需要一个代表“第n层”的队列,每次都会将当前层 ,全部能继续 “往下“ 元素 压进队列去,
然后横向剪 “邻枝” 或者说,排除邻支,以及包括从邻支到底层的所有可能,所以效率特别高,
即:搜索时首先将初始状态加到队列里,此后队列的最前端不断取出状态,(某层第x个元素)
把从该状态可以转移到的状态中尚未访问过的部分,但是又能访问下去的,加入队列(同一层的),
如此反复,直至队列被取空或找到了问题的解。因此确定宽度也很重要。
观察这个队列,我们可以发现所有的状态都是按照距离初始状态由近及远的顺序进入的。
又因为它是queue实现,先进先出,一定按照从前到后的次序,来“剪枝”/记录“路径”/“遍历”
因此,如果是bfs 特征一定是,它判断“成功”的条件,不需要到最底层,在当前层就已经可以排除掉,可以“预判”,可以在上层剪枝
所以适合——迷宫/找最小全“1”/“0”或者某一条件的矩阵,又或者同样可以用dfs解决但是对“更高效率”有要求的题目
如下为一般结构:
bfs(){
初始点入列
while(终止条件不满足 或 队列不为空){//层数不为0
队列头出列 //更新队列,更新新的扩散出发点
for() //从出列元素开始扩散,满足的就入列 ,一般是一个循环,满足的意思是,满足后面还可以继续往下的就入列
找个数组记下来目标值
}
找目标值
}
为了理解,局这样一个栗子,1,2,3,4,5,6,7 假设分支是1—2,4 ;2—3,5,7; 4—6,那么过程就是,
1先入列做为起点,
进入循环,出列,
开始以1为起点for扩散,检查到1的儿子有2,4,加入队列,此时队列为4,2,for循环结束,
此时队伍不为空,while循环继续,
此时队列为4,2,队列先进先出(也可以理解为栈结构栈尾出),所以2先出来,进入循环,以2为起点扩散,找到3,5,7
加进队列,此时队列为7,5,3,4,所以之后下一个起点的会是4,
4后面的6加入之后,3,5,7再依次做起点,直到6,检查完结束
bfs和dfs辨析—基础复习(从stack和queue的角度来理解区别,加深理解,不再模糊)的更多相关文章
- C#基础复习(1) 之 Struct与Class的区别
参考资料 [1] 毛星云[<Effective C#>提炼总结] https://zhuanlan.zhihu.com/p/24553860 [2] <C# 捷径教程> [3] ...
- 算法基础:BFS和DFS的直观解释
算法基础:BFS和DFS的直观解释 https://cuijiahua.com/blog/2018/01/alogrithm_10.html 一.前言 我们首次接触 BFS 和 DFS 时,应该是在数 ...
- 【算法】二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现记录(Java版)
本文总结了刷LeetCode过程中,有关树的遍历的相关代码实现,包括了二叉树.N叉树先序.中序.后序.BFS.DFS遍历的递归和迭代实现.这也是解决树的遍历问题的固定套路. 一.二叉树的先序.中序.后 ...
- HDU-4607 Park Visit bfs | DP | dfs
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 首先考虑找一条最长链长度k,如果m<=k+1,那么答案就是m.如果m>k+1,那么最 ...
- 用BFS和DFS解决圆盘状态搜索问题
人工智能课程的实验(我的解法其实更像是算法课程的实验) 用到的算法:深度优先搜索.宽度优先搜索(状态扩展的不同策略) 数据结构:表示状态的结构体.多维数组 (可能是最近做算法竞赛题的影响,这次并不像以 ...
- 算法录 之 BFS和DFS
说一下BFS和DFS,这是个比较重要的概念,是很多很多算法的基础. 不过在说这个之前需要先说一下图和树,当然这里的图不是自拍的图片了,树也不是能结苹果的树了.这里要说的是图论和数学里面的概念. 以上概 ...
- 【数据结构与算法】自己动手实现图的BFS和DFS(附完整源码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/19617187 图的存储结构 本文的重点在于图的深度优先搜索(DFS)和广度优先搜索(BFS ...
- BFS、DFS、先序、中序、后序遍历的非递归算法(java)
一 广度优先遍历(BFS) //广度优先遍历二叉树,借助队列,queue public static void bfs(TreeNode root){ Queue<TreeNode> qu ...
- ACM__搜素之BFS与DFS
BFS(Breadth_First_Search) DFS(Depth_First_Search) 拿图来说 BFS过程,以1为根节点,1与2,3相连,找到了2,3,继续搜2,2与4,相连,找到了4, ...
随机推荐
- 为什么Mysql的常用引擎都默认使用B+树作为索引?
一.前言 为了讲清楚这个问题,我们要先了解什么是索引. 我记得刚刚学习数据库的时候,老师喜欢用书本的目录来类比数据库的索引,并告诉我们索引能够像目录一样,让我们更快地找到想要找到的数据. 如果是第一次 ...
- IDEA报错:Could not find resource com/liwen/bean/userMapper.xml
主要原因设idea无法识别src路径下的xml文件,要把xml文件建立在resources文件下
- 终极解决方案之——Centos7由于误删或更新python导致 No module named yum
之前由于不懂yum和python之间的关系,因为一直在学python3,看到系统里/usr/lib下的python2我就直接删了,结果... 可能还有人是因为python升级的原因,即系统自带的pyt ...
- 特征选择与稀疏学习(Feature Selection and Sparse Learning)
本博客是针对周志华教授所著<机器学习>的"第11章 特征选择与稀疏学习"部分内容的学习笔记. 在实际使用机器学习算法的过程中,往往在特征选择这一块是一个比较让人模棱两可 ...
- 强化学习之四:基于策略的Agents (Policy-based Agents)
本文是对Arthur Juliani在Medium平台发布的强化学习系列教程的个人中文翻译,该翻译是基于个人分享知识的目的进行的,欢迎交流!(This article is my personal t ...
- Building Applications with Force.com and VisualForce (DEV401) (二二):Visualforce Componets (Tags) Library Part II
Dev401-023:Visualforce Pages: Visualforce Componets (Tags) Library Part II Apex:pageBlockTable1.A ...
- 一个完整的机器学习项目在Python中的演练(二)
大家往往会选择一本数据科学相关书籍或者完成一门在线课程来学习和掌握机器学习.但是,实际情况往往是,学完之后反而并不清楚这些技术怎样才能被用在实际的项目流程中.就像你的脑海中已经有了一块块"拼 ...
- Python第十一章-常用的核心模块01-collections模块
python 自称 "Batteries included"(自带电池, 自备干粮?), 就是因为他提供了很多内置的模块, 使用这些模块无需安装和配置即可使用. 本章主要介绍 py ...
- Ubuntu系统安装wxPython问题
wxPython介绍 wxPython是Python语言的GUI工具包,作为Python的扩展模块实现,包装了wxWidgets.wxPython是跨平台的,开源的.详情 wxPython安装 (1) ...
- 20175314 《Java程序设计》第十周学习总结
20175314 <Java程序设计>第十周学习总结 教材学习内容总结 进程与线程:一个进程的进行期间可以产生多个线程. Java内置对多线程的支持,计算机只能执行线程中的一个,Java虚 ...