DFS搜索算法--(1)基础图遍历 绝对看!的!懂!
内容总结 自《啊哈!算法!》
作为一个都大二的了一个菜鸡,做题的时候DFS怎么可以不会呢!!!
作为一个都大二了的(!!!)菜鸡....《啊哈算法》这本书第四章的搜索,开始那里我就没看懂,就跑来看第五章了。结果这个理解起来方便一些....总结摘抄一下给远方的不知名网友and for myself。
以下语言有不严谨之处请多包涵,先理解重要。
深度搜索算法,就是对于一个图(图自己瞎画的 太丑) 如下图所示,给这些圆圈标号。

然后我们遍历的时候,是“优先深度” ,先从一条路走到黑走不动了再换条道继续一条路走到黑。即先从1开始,走到2,走到5. 然后走不动了就先回去,先回到2,发现还有6可以走,然后又走到6了。然后又走不动了。便回到2,但是2的所有支路已经都被访问过了,那就再往回走一个,走到1。 回到1以后,2这条道已经走完了,就走到3,再走到7,走不动了再回到3,3没有别的支路可以走了就再回到1,然后再走4
那么上图的访问顺序是(不算重复的顶点):1 2 5 6 3 7 4
如果一条道走完了,比如说从2走到5,走完了,就要回到上一个路口顶点2。从5到2的过程称为回溯。
那么如何存储一个图呢?我们用一个二维数组arr来存储:


如上两个图所示,二维数组中第i行第j列表示的就是顶点i到顶点j是否有边。1表示有边,空着的就是没有边(在编程时可以将其赋值为9999,画图太麻烦我就省去了) ,二维数组行和列相等的我赋值为0.
能看到,上面的这个图是关于主对角线对称的,这是因为这个图是个‘无向图’。也就是这个图的边没有方向,从1到2和从2到1是一样的,所以 arr[ 2 ] [ 1 ] = arr[ 1 ][ 2 ] = 1。
以下是代码实现:
其中,book[ ] 这个数组一开始全部赋初值为0,表示未被访问过。被访问赋值为1。
还有一个需要知道的小知识点,就是我的代码内又两个return,第一个return表示函数结束,第二个return表示返回上一个dfs()函数,这是递归函数的特殊用法。比如:现在是dfs(5),执行代码时遇到了代码中第二个return,然后就会返回上一个执行的dfs()函数,这就变成了dfs(2),这个过程就是回溯。
void dfs(int cur)//cur是当前在的顶点的编号
{
printf("%d ",cur);//按顺序打印出遍历过的点
sum++;//sum是全局变量,初值为0。每访问一个点,sum++。
if(sum==n)
return ;//n为全局变量,是总共点的数量。若sum==n,便是点都访问完了,就退出函数。 for(int i=;i<=n;i++)//从1号点到n号点依次尝试,看看谁与cur点相连着
{
if(arr[cur][i]==&&book[i]==)//若这个点没有被访问过并且与cur相连
{
book[i]=;//把这个点标记为已访问
dfs(i);//递归,继续从这个点再继续深入遍历
}
}
return ;//当与cur相连的所有点都已被访问过了,就返回到上一个dfs()
}
完整代码如下:
#include<iostream>
#include<cstdio>
using namespace std; int book[],sum,n,arr[][]; void dfs(int cur)//cur是当前在的顶点的编号
{
printf("%d ",cur);//按顺序打印出遍历过的点
sum++;//sum是全局变量,初值为0。每访问一个点,sum++。
if(sum==n)
return ;//n为全局变量,是总共点的数量。若sum==n,便是点都访问完了,就退出函数。 for(int i=;i<=n;i++)//从1号点到n号点依次尝试,看看谁与cur点相连着
{
if(arr[cur][i]==&&book[i]==)//若这个点没有被访问过并且与cur相连
{
book[i]=;//把这个点标记为已访问
dfs(i);//递归,继续从这个点再继续深入遍历
}
}
return ;//当与cur相连的所有点都已被访问过了,就返回到上一个dfs()
} int main()
{
sum=;
int m,a,b;
cin>>n>>m;//m表示有几条边 n表示有几个点
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i==j)
arr[i][j]=;
else
arr[i][j]=;//把没有边相连的标记为999999
}
} //读入顶点之间的那些边
for(int i=;i<m;i++)
{
cin>>a>>b;
arr[a][b]=;
arr[b][a]=;//由于时无向图,所以两个都要标记。在前面我说过了
}
book[]=;//从1号顶点出发。标记1号顶点已经被访问
dfs(); getchar();getchar(); return ;
}
ok fine 那么简单图遍历就说完了 下次继续写
DFS搜索算法--(1)基础图遍历 绝对看!的!懂!的更多相关文章
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
- 【算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细一看就懂的解析
更多精彩尽在微信公众号[程序猿声] 变邻域搜索算法(Variable Neighborhood Search,VNS)一看就懂的解析 00 目录 局部搜索再次科普 变邻域搜索 造轮子写代码 01 局部 ...
- 一看就懂的ReactJs入门教程(精华版)
一看就懂的ReactJs入门教程(精华版) 现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和 ...
- python中和生成器协程相关yield from之最详最强解释,一看就懂(二)
一. 从列表中yield 语法形式:yield from <可迭代的对象实例> python中的列表是可迭代的, 如果想构造一个生成器逐一产生list中元素,按之前的yield语法,是在 ...
- 一看就懂的Android APP开发入门教程
一看就懂的Android APP开发入门教程 作者: 字体:[增加 减小] 类型:转载 这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤 ...
- mysql取出现在的时间戳和时间时间戳转成人类看得懂的时间
mysql取出现在的时间戳和时间时间戳转成人类看得懂的时间,我们在mysql里面他封装了一个内置的时间戳转化的函数,比如我们现在的时间戳是:1458536709 ,"%Y-%m-%d&quo ...
- JavaScript一看就懂(2)闭包
认识闭包之前需要先了解作用域,如果你对作用域还没有足够了解,请移步JavaScript一看就懂(1)作用域 什么是闭包? 我们可以先简单认为:一个函数a定义在另一个函数b里面,这个函数a就是闭包: f ...
- 小学生都看得懂的C语言入门(1): 基础/判别/循环
c基础入门, 小学生也可以都看得懂!!!! 安装一个编译器, 这方面我不太懂, 安装了DEV-C++ ,体积不大,30M左右吧, 感觉挺好用,初学者够了. 介绍下DEV 的快键键: 恢复 Ctrl+ ...
- python中和生成器协程相关的yield from之最详最强解释,一看就懂(四)
如果认真读过上文的朋友,应该已经明白了yield from实现的底层generator到caller的上传数据通道是什么了.本文重点讲yield from所实现的caller到coroutine的向下 ...
随机推荐
- Python基础之格式化输出
有一个需求,问用户的姓名,年龄,工作,爱好,然后打印成以下格式: -----------info of yangwei--------------- Name : yangwei Age : 22 J ...
- Jmeter(十二)常用插件
一.下载及安装 下载地址:https://jmeter-plugins.org/install/Install/ 下载后文件为一个jar包,将其放入jmeter安装目录下的lib/ext目录,然后重启 ...
- CTF MD5之守株待兔,你需要找到和系统锁匹配的钥匙
这是提示 从系统锁下手,通过get方式key字段提交答案,直到您的钥匙与系统锁相等则成功. 点开链接可以发现有两串字符,而且系统的秘钥是一直在变化的 题目中已经给了MD5加密,那么用MD5解密发现您的 ...
- zookeeper系列(三)zookeeper的使用--开源客户端
作者:leesf 掌控之中,才会成功:掌控之外,注定失败, 原创博客地址:http://www.cnblogs.com/leesf456/ 奇文共欣赏,大家共同学习进步. 一.前言 上一篇博客已 ...
- 使用root配置的hadoop启动时报错
一.报错信息: Starting namenodes on [master] ERROR: Attempting to operate on hdfs namenode as root ...
- 软工团队Git现场编程实战
组员职责分工 成员 分工 鲍子涵 分配职责,整合代码 吴宜航 UI设计与实现 钟博 UI设计与实现(Main Coder) 黄海东 数据整理 王镇隆 前端api接口分析和使用(Main Coder) ...
- 十大经典排序算法最强总结(含JAVA代码实现)(转)
十大经典排序算法最强总结(含JAVA代码实现) 最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每 ...
- Qt qss 动态属性-不同条件不同显示
一. 1.为了用户界面外观的动态变化,属性选择器可以与动态属性组合使用. 2.当一个属性值变化时,所引用的样式不会自动更新.相反地,必须手动触发更新才会生效.unpolish()用于清理之前的样式,而 ...
- MSSQL字符串取相应的第几个数组值
create function Get_StrArrayStrOfIndex( @str varchar(5000), --要分割的字符串 @split varchar(10), --分隔符号 @in ...
- Vue组件中的data属性
Vue中的data属性专门用来以对象方式存放数据,它有两种用法. var vm=new Vue({ data:{a:1,b:2,}, }) var vm=new Vue({ data(){return ...