DFS(深度优先搜索算法)入门保姆级超详解

这篇具有很好参考价值的文章主要介绍了DFS(深度优先搜索算法)入门保姆级超详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如题,本篇创作目的在于更精细化理解DFS的运作,篇幅不长,也只是作者的一家之言,只为提供一个对入门者的更精细的解释。

DFS,深度优先搜索算法,首先我们看中文,可以很清楚的理解到这个算法是指搜索操作中优先进行深度也就是纵向的数据筛查。

看搜索的基本思路:

360百科:

当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

百度百科/维基百科(两个是一样的):

深度优先遍历图的方法是,从图中某顶点v出发:

(1)访问顶点v;

(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 当然,当人们刚刚掌握深度优先搜索的时候常常用它来走迷宫.

 那么按照我们粗浅的理解,提取关键信息和重复信息,我们可以得到以下概念:

1.重复性很高,很多操作都非常相似或者相同。

2.需要系统资源相对大,属于盲目搜索所有的可能信息,并且比较“笨拙”,也就是傻瓜式方法,所以有特殊限制条件。

3.每个结点都是有可预估方向的。

我们需要外引几个概念:树,决策树,递归,遍历。

首先树相信大家也并不陌生,当然不知道的最好赶紧补一补了嗷。决策树,解决问题常用,这里的使用用于理解。递归,递归这个东西很魔幻很玄乎,一定要好好学啊,太抽象了。遍历,一般是指树的遍历,这里我们暂时只用到中序遍历,不了解的建议补一下,这里暂时不多做说明。

dfs算法,算法,深度优先,算法,经验分享,图论,c++

这是一个标准二叉树 (只看到15)

中序遍历的结果:1-2-4-8-9-5-10-11-3-6-12-13-7-14-15

为什么我要说到中序遍历,看中序遍历结果,是不是顺序和深度优先字面意思符合呢?因为中序遍历是非常直观地展示DFS也就是深度优先算法的结果,并且符合决策树的顺序判断。例如我们测星座运势(或者性格测试,挺老套的),如图有8个结果,其中要经过两个问题,每个问题有两个选项,一共6种事件,所有结果产出走向为:

结果一: 1-2-4-8

结果二: 1-2-4-9

结果三: 1-2-5-10

......

结果七: 1-3-7-14

结果八: 1-3-7-15

可以发现如果划掉中序遍历的一部分结点标号,可以截出来所有结果。

深度优先搜索其核心就是先一路搜到底,然后返回上一个结点换条路继续一路搜到底

上述仅仅为DFS的一种,这里我们只讨论思路入门,不做过多实例。

为什么我们又提到了递归,递归的定义看似简单,就是函数本身的再调用,但是实际上水深着呢,比如说传参,可以不需要特地使用额外的容器保存数据就可以使用与递归调用相关的数据

为DFS举例: 单向迷宫

存在这样一个奇怪的迷宫,你需要闯关9个关卡,并且全部通关才能打开出口 ,默认你在1号关卡,问有多少种通关的路线?

dfs算法,算法,深度优先,算法,经验分享,图论,c++

其实这就是一个简单的九宫格图遍历的问题,我们先给出答案再做分析

代码:

#include<iostream>
using namespace std;
	
int k[3][3] = {1,2,3,4,5,6,7,8,9};
//关卡标号 
int square[3][3]={0};
//3*3的方格 
int x[4] = {0,1,0,-1};
int y[4] = {1,0,-1,0};
//记录下一步的坐标,x为水平,y为垂直,默认左上为正方向,搜索顺序为右下左上 
int total;
//int型默认值为0

void dfs(int xi,int yi,int step,string s)
{
	int tx,ty;
	//保存下一关卡坐标 
	if(step == 9)
	{
		total++;
		//9个关卡闯关完成为一条闯关路线,路线计数+1 
		cout<<"第"<<total<<"条搜闯关路线为: "<<s<<endl;
		//输出每条路线的具体闯关标号顺序 
		return ;
		//结束本层递归函数返回上一层 
	}
	for(int i=0;i<4;i++)//i<4因为四个方向,数组下标0开始 
	{
		tx = xi + x[i];
		ty = yi + y[i];
		//保存下一个关卡的坐标 
		if(tx<0||tx>=3||ty<0||ty>=3)
			continue;
			//如果下一关卡在地图外则跳过换一个方向 
		if(square[tx][ty]==1)
			continue;
			//如果下一关卡已经成功闯关则换一个方向 
		square[tx][ty]=1;
		//闯关本关,我更愿意理解为种草(要问就是1像草) 
		dfs(tx,ty,step+1,s+"->"+char('0'+k[tx][ty]));
		//递归,注意每次递归step+1指种草数 
		square[tx][ty]=0;
		//拔草 
	}
}
int main()
{
	square[0][0]=1;
	//从第一关开始 
	dfs(0,0,1,"1");
	//string s赋值1从第一关开始记路线 
	cout<<"一共"<<total<<"条闯关路线";
	return 0;            
}

结果:

dfs算法,算法,深度优先,算法,经验分享,图论,c++

基本每一行代码都有注释,可以说是很详细了,但是关于递归有一个非常重要非常女少口阿的点,我们分析一下题目闯关方式,用决策树分析一部分模型 

 dfs算法,算法,深度优先,算法,经验分享,图论,c++

数字就是闯关标号,可以看到我只列举了两条完整的路线,其余的都是一层横向拓展的 

第一条路线: 1-2-3-6-9-8-7-4-5

第二条路线: 1-2-3-6-9-8-5-4-7

可以发现这两条路线差别就在于第八关的选择方向,这就需要提到这个递归的妙处了

void dfs(int xi,int yi,int step,string s)

xiyi应该不用多做解释,stepstring就有的说了

dfs算法,算法,深度优先,算法,经验分享,图论,c++

首先是stepstep的作用不仅仅在于标出当前的种草数(不知道的先去看看代码注释),它的关键在于当前递归层的层数,看一下递归的调用以及下一句:

dfs(tx,ty,step+1,s+"->"+char('0'+k[tx][ty]));
square[tx][ty]=0;

你可以看到你并没有保存step的具体数据,每一次的调用都是step+1,那么下一层递归的step-1就是当前层的step ,比如说此时step = 9了一条闯关路线结束return结束函数,那么回到上一层此时step = 8并且下一步拔草,具体点:

到第八关 8-> 有两条路线下一步是7或者是5

选择7:此时为一路运行到递归调用到的第七层 step = 7 接下来只有一条路->4->5,此时为递归第九层 step = 9 关卡5,因为直接调用递归所以递归下一句拔草并没有执行,等到return要结束最外一层递归的时候,最后一个关卡是没有种草的,也同时不需要拔草,接下来回到上一层 step = 8 关卡4,开始拔草,这次拔草拔的是这层种的草,拔完for循环继续发现其余方向都会continue,第八层递归结束回到上一层第七层 step = 7 关卡7,继续拔草拔本层的草,继续拔完for循环发现其余方向都是continue,第七层递归结束,回到上一层第六层 step = 6 关卡8,然后继续拔草把本层的草,继续拔完后for循环发现下一个方向可以走关卡5,于是继续调用递归开始寻找下一个闯关路线。

以上细节多多,第一遍可能看的有点混乱,多看几遍就好了。

string s 同理,每一层的step对应每一次不同的string s,每次递归回退都会消除外一层递归增加的内容。

DFS适合用于穷举计算,也就是穷尽每一种情况,傻瓜式的计算,其核心在于递归的使用,希望我上面的一些想法给你带来新的理解,如果你觉得我讲的不错可以点个赞支持一下另外如果绝对我哪里讲的不好或者有补充请在评论区说出文章来源地址https://www.toymoban.com/news/detail-733038.html

到了这里,关于DFS(深度优先搜索算法)入门保姆级超详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言递归+DFS(深度优先搜索算法)详解 图文并茂,手把手教你画树状图

    目录 一.标准定义 二.跳台阶(典型递归题目) 三.递归实现指数型枚举 四.递归实现排列型枚举 五.递归实现组合型枚举 六.DFS算法模板 深度优先搜索算法(Depth First Search,简称DFS): 一种用于遍历或搜索树或图的算法 。 沿着树的深度遍历树的节点, 尽可能深的搜索树的分

    2024年02月04日
    浏览(57)
  • 【数据结构与算法】图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )

    图 的 遍历 就是 对 图 中的 结点 进行遍历 , 遍历 结点 有如下两种策略 : 深度优先搜索 DFS 广度优先搜索 BFS \\\" 深度优先搜索 \\\" 英文名称是 Depth First Search , 简称 DFS ; DFS 基本思想 : 访问第一个邻接结点 : 从 起始点 出发 , 该 起始点 可能有 若干 邻接结点 , 访问 第一个 邻接结点

    2024年02月02日
    浏览(38)
  • 深度优先搜索(DFS)算法

    目录 算法思想 时间复杂度和空间复杂度 算法实现 算法优缺点 应用领域 深度优先搜索(DFS)算法的思想是从图的某个起始顶点开始,沿着一条路径尽可能深入地访问图中的所有顶点,直到不能继续为止,然后返回并探索其他路径。具体而言,DFS算法使用栈数据结构来实现,

    2024年02月05日
    浏览(38)
  • 深度优先搜索(DFS)(算法笔记)

    本文内容基于《算法笔记》和官方配套练题网站“晴问算法”,是我作为小白的学习记录,如有错误还请体谅,可以留下您的宝贵意见,不胜感激。 深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法,总是以“深度”作为前进的。实现方式是有很多,最

    2024年02月08日
    浏览(42)
  • [算法日志]图论: 深度优先搜索(DFS)

    ​ 深度优先搜索算法是一种遍历图这种数据结构的算法策略,其中心思想是朝图节点的一个方向不断跳转,当该节点无下一个节点或所有方向都遍历完时,便回溯朝上一个节点的另一个方向继续遍历。这种搜索策略与回溯法有异曲同工之妙。 正因为和回溯法有相似之处,所

    2024年02月03日
    浏览(53)
  • 第一周算法训练(dfs)(深度优先搜索算法)

    dfs: 深度优先搜索算法 ,是一种用于遍历或 搜索树或图的算法 .沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被

    2024年02月20日
    浏览(43)
  • 深度优先搜索(DFS)和广度优先搜索(BFS)两种算法c++

    深度优先搜索(DFS)和广度优先搜索(BFS)是一种用于遍历或搜索树图的一种算法,在这个过程中保证图或数的每个结点被访问且仅被访问一次,再按照每个结点访问的顺序不同分为深搜和广搜。 本文只讨论这两种算法在搜索方面的应用! 深度优先搜索 ( Depth-First-Search,DFS )它 沿

    2024年02月13日
    浏览(38)
  • Python 算法基础篇:深度优先搜索( DFS )和广度优先搜索( BFS )

    深度优先搜索( DFS )和广度优先搜索( BFS )是两种常用的图遍历算法,用于在图中搜索目标节点或遍历图的所有节点。本篇博客将介绍 DFS 和 BFS 算法的基本概念,并通过实例代码演示它们的应用。 😃😄 ❤️ ❤️ ❤️ 深度优先搜索( DFS )是一种用于遍历或搜索图或树

    2024年02月07日
    浏览(59)
  • 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次。(连通图与非连通图) 1、访问指定的起始顶点; 2、若当前访问的顶点的邻接顶点有未被访问的,则任选一个访问之;反之,退回到最近访问过的顶点;直到与起始顶点相通的全部顶点都访问完毕; 3、若

    2024年01月17日
    浏览(39)
  • 【数据结构与算法】搜索算法(深度优先搜索 DFS和广度优先搜索 BFS)以及典型算法例题

    【数据结构与算法】系列文章链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题) 【数据结构与算法】系列文章链接: 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题 【数据结构与算法】系列文章链

    2024年04月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包