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的向下 ...
随机推荐
- 二叉树的序遍历x(内含结构体与非结构体版x)
3143 codevs 二叉树的序遍历 题目描述 Description 求一棵二叉树的前序遍历,中序遍历和后序遍历 输入描述 Input Description 第一行一个整数n,表示这棵树的节点个 ...
- vue-cli3项目打包后,在自己搭的服务器上访问打包好的页面空白,处理方法
我用vue开发的一个小项目,项目开发出雏形,想打包一下放测试,但是我想放测试前自己检查一下经过npm run build打包生成的项目,在本地服务器能不能正常跑,于是,经过网上大哥的帮忙,写了个简易的 ...
- npm安装cnpm时候报错code EINTEGRITY
npm安装cnpm时候报错code EINTEGRITY错误展示 PS C:\Users\by\Desktop\element_ui_demo> npm install --g npmnpm ...
- LOJ #2733 [JOI2016春季合宿]Sandwiches (DP)
题目链接 https://loj.ac/problem/2733 题解 神仙题-- 首先可以观察到一个结论: 目标块的两块小三明治一定分别是最后和倒数第二个被吃的. 由此我们可以考虑这两块谁先被吃.这 ...
- AcWing:172. 立体推箱子(bfs)
立体推箱子是一个风靡世界的小游戏. 游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示).易碎地面(用”E”表示).禁地(用”#”表示).起点(用”X”表示)或终点(用”O”表示). 你的 ...
- gRPC-Web正式发布
前言: gRPC-Web是一个JavaScript客户端库,可以使Web应用程序直接与后端gRPC服务进行通信,而无需HTTP服务器充当中介. 这意味着可以通过使用.proto文件定义客户端和服务器端 ...
- $\LaTeX$数学公式大全2
$2\ Math\ Constructs$$\frac{abc}{xyz}$ \frac{abc}{xyz}$f'$ f'$\sqrt{abc}$ \sqrt{abc}$\sqrt[n]{abc}$ ...
- python3笔记二十四:Mysql数据库操作命令
一:学习内容 Mysql操作命令:启动服务.停止服务.连接数据库.退出数据库.查看版本.显示当前时间.远程连接 数据库操作命令:创建数据库.删除数据库.切换数据库.查看当前选择的数据库 表操作命令:查 ...
- java实现一个简单的验证码生成器
最近看了网上很多大佬们写的验证码生成,寻思着自己也写一个,话不多说,代码如下: import java.awt.BasicStroke; import java.awt.Color; import j ...
- Odp.Net 连接Oracle
1.C#连接Oracle可以不安装客户端,但是需要借助Odp.net 免安装Oracle客户端: 将5个Oracle客户端的类库文件提取出来,放到程序根目录下,分别是oci.dll.Oracle.Da ...