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, ...
随机推荐
- SpringMVC框架——自定义数据类型转换器
Spring MVC 框架的 Converter<S,T> 是一个可以将一种数据类型转换成另一种数据类型的接口,这里 S 表示源类型,T 表示目标类型. 开发中如果需要自定义数据类型转换时 ...
- Swift 4.0 中的错误处理及抛出错误
在Swift的标准库,很多方法名后都带有'throws'这个关键词, 'throws'表示该方法在执行过程中遇到错误则抛出,但不会crash. 下面是Swift标准库中的一个构造方法,String.D ...
- 内置函数---filter和map
filter filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回 ...
- dfs 例题皇后问题
题目描述 一个如下的 6 \times 66×6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列 ...
- 使用docker构建双主mysql
我们有的时候需要双主mysql, 这样无论哪个数据库出现了问题的话都可以继续使用数据库.把两个数据库挂到一个代理上面,这样哪个服务出问题了,另外一个就可以继续服务了.当然本文不是主要谈代理的,所以这个 ...
- 基础的linux命令(一)
我练习使用的 Linux 系统是 CentOS 7 它是通过把 RHEL 系统重新编译并发布给用户免费使用的 Linux 系统. 首先你需要一台Linux虚拟机,如果没有,也没关系,点这里 一.命令格 ...
- [树的深度] Party
Party A company has n employees numbered from 1 to n. Each employee either has no immediate manager ...
- Python——迭代器的几个高级用法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第8篇文章. 今天我们依然介绍的是迭代器,不过介绍的是几个比较常用的高级用法,在实际场景当中非常实用,可以帮助我们大 ...
- Python第五章-内置数据结构02-列表
Python 内置的数据结构 二.列表(list) 想一想: 前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢? 定义100个变量,每个变量存放一个学生的姓名可行吗?有 ...
- 扩展KMP(记录学习过程)
首先看了几篇博客,发现还得耐下心来理解,动手画图 ,才能理解俩字符串还有数组之间神奇的关系 这篇博客图不错:https://segmentfault.com/a/1190000008663857 /* ...