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的向下 ...
随机推荐
- 洛谷P3193 GT考试 kmp+矩阵优化dp
题意 求\(N\)位数字序列(可以有前导0)中不出现某\(M\)位子串的个数,模\(K\). \(N<=10^9,M<=20,K<=1000\) 分析 设\(dp[i][j]\)表示 ...
- Centos 7 安装 Xilinx SDSoC Development Environment
1.CentOS版本信息 $ cat /etc/redhat-releaseCentOS Linux release 7.6.1810 (Core) 2.SDSoC下载地址: https://www. ...
- CentOS7 升级Openssl的办法
1.查看安装的版本 openssl version -a OpenSSL 1.0.2 2.下载 openssl-1.1.1.tar.gz,目前最新是1.1.1,可以通过修改版本号的方式下载最新版本 最 ...
- Spring Boot教程(三十六)使用MongoDB数据库(2)
快速开始使用Spring-data-mongodb 若MongoDB的安装配置采用默认端口,那么在自动配置的情况下,我们不需要做任何参数配置,就能马上连接上本地的MongoDB.下面直接使用sprin ...
- 2、dubbo基础知识
1.简介 2.dubbo架构 3.dubbo环境搭建 注意:cmd命令都是在bin目录的地址栏直接输入 xxx.cmd 4.配置dubbo-admin 步骤一: 步骤二: 步骤三: 步骤四: 步骤五: ...
- PHP-过滤器-连接数据库-解析XML
PHP 过滤器 what? PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入. 验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分. 设计 PHP 的过滤器扩展的目的 ...
- Netty入门官方例子
参考链接:https://blog.csdn.net/wocjy/article/details/78661464 maven依赖: <!-- Netty开始 --> <!-- ht ...
- SRS之分发HLS
来自: Delivery HLS 1. 综述 SRS支持HLS/RTMP两种成熟而且广泛应用的流媒体分发方式. RTMP指Adobe的RTMP(Realtime Message Protocol),广 ...
- better-scroll 介绍
碰到一个项目,应该遵守两大规则: 1. 不要让项目产生过多的第三方依赖 2. 增强组件的应用率 尽可能的将东西写在组件里面,尽可能的将数据写活,通过组件通信来进行数据转换,用到的依赖处理,我们可以通过 ...
- php改变header头返回值
$code = '400 Bad Request'; header('HTTP/1.1 '.$code);