参考:

https://www.cnblogs.com/Tovi/articles/6194815.html

https://blog.csdn.net/dangzhangjing97/article/details/81477192

https://blog.csdn.net/qq_39747794/article/details/84478771?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

一般来说,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的角度来理解区别,加深理解,不再模糊)的更多相关文章

  1. C#基础复习(1) 之 Struct与Class的区别

    参考资料 [1] 毛星云[<Effective C#>提炼总结] https://zhuanlan.zhihu.com/p/24553860 [2] <C# 捷径教程> [3] ...

  2. 算法基础:BFS和DFS的直观解释

    算法基础:BFS和DFS的直观解释 https://cuijiahua.com/blog/2018/01/alogrithm_10.html 一.前言 我们首次接触 BFS 和 DFS 时,应该是在数 ...

  3. 【算法】二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现记录(Java版)

    本文总结了刷LeetCode过程中,有关树的遍历的相关代码实现,包括了二叉树.N叉树先序.中序.后序.BFS.DFS遍历的递归和迭代实现.这也是解决树的遍历问题的固定套路. 一.二叉树的先序.中序.后 ...

  4. HDU-4607 Park Visit bfs | DP | dfs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 首先考虑找一条最长链长度k,如果m<=k+1,那么答案就是m.如果m>k+1,那么最 ...

  5. 用BFS和DFS解决圆盘状态搜索问题

    人工智能课程的实验(我的解法其实更像是算法课程的实验) 用到的算法:深度优先搜索.宽度优先搜索(状态扩展的不同策略) 数据结构:表示状态的结构体.多维数组 (可能是最近做算法竞赛题的影响,这次并不像以 ...

  6. 算法录 之 BFS和DFS

    说一下BFS和DFS,这是个比较重要的概念,是很多很多算法的基础. 不过在说这个之前需要先说一下图和树,当然这里的图不是自拍的图片了,树也不是能结苹果的树了.这里要说的是图论和数学里面的概念. 以上概 ...

  7. 【数据结构与算法】自己动手实现图的BFS和DFS(附完整源码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/19617187 图的存储结构 本文的重点在于图的深度优先搜索(DFS)和广度优先搜索(BFS ...

  8. BFS、DFS、先序、中序、后序遍历的非递归算法(java)

    一 广度优先遍历(BFS) //广度优先遍历二叉树,借助队列,queue public static void bfs(TreeNode root){ Queue<TreeNode> qu ...

  9. ACM__搜素之BFS与DFS

    BFS(Breadth_First_Search) DFS(Depth_First_Search) 拿图来说 BFS过程,以1为根节点,1与2,3相连,找到了2,3,继续搜2,2与4,相连,找到了4, ...

随机推荐

  1. AI学习笔记:人工智能与机器学习概述

    一.人工智能基本概念 1.1 基本概念 数据分析:对历史规律的展现.对未来数据的预测. 机器学习:机器学习是指从一系列的原始数据中找到规律,提取人们可以识别的特征,然后通过学习这些特征,最终产生一个模 ...

  2. python基础知识1——简介与入门

    什么是Python:Python能做什么:安装与更新:第一个Python程序:变量:pyc字节码:编码:条件和循环:Python运算符:算数,比较,赋值,位,逻辑::::::::::::::::::: ...

  3. wr720n v4 折腾笔记(二):刷入不死Uboot

    0x01 前言 接着上节刷入Openwrt开始说起,此次开始刷入不死Uboot,刷入之后就可以在Uboot里面随便刷机,再也不怕成砖了. 固件附件地址: 下载地址1(还是之前一的包) flash文件地 ...

  4. 加油站问题 Gas Station

    2019-06-01 17:09:30 问题描述: 问题求解: 其实本题本质上是一个数学题. [定理] 对于一个循环数组,如果这个数组整体和 SUM >= 0,那么必然可以在数组中找到这么一个元 ...

  5. 动态规划/MinMax-Predict the Winner

    2018-04-22 19:19:47 问题描述: Given an array of scores that are non-negative integers. Player 1 picks on ...

  6. Javascript之封装运动函数

    @ 目录 阶段一.仅适用单位带px属性的匀速运动 阶段二.可适用单位不带px属性(如opacity)的匀速运动 阶段三.适用于多元素单一属性的匀速运动 阶段四.适用于多元素单一属性的匀速或缓冲运动 阶 ...

  7. 报错:Error updating database. Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'gender' at row 1

    我遇到这个错误是解决办法:我修改了对应的数据库字段的长度:原本我设置的是char型,但是存进去的是一个string型,结果就报了这个报了这个错误 下面就是数据库修改之后的结果. 以上都是我学习过程中遇 ...

  8. k8s可视化工具kubernetes-dashboard部署——小白教程

    参考资料: kubernetes官方文档 官方GitHub 创建访问用户 解决chrome无法访问dashboard 官方部署方法如下: kubectl apply -f https://raw.gi ...

  9. vue-父组件传递参数到子组件

    案例: 父组件 <template> <div id="app"> <h1>vuex</h1> <h3>count:{{ ...

  10. js数组的常用方法(10种)

    数组的常用方法 数组在JavaScript中经常使用,如何对数组进行增删改非常重要,下面为数组的常用方法: 在数组末尾插入元素 arr.push(value),在数组的末尾添加一个或多个元素,并返回数 ...