深度搜索(DFS)

点;然后退回到该顶点,搜索其它路径,直到以该顶点为始点的所有路径的顶点都被访问,深度搜索算法是递归算法,因为对于没一个节点来说,执行的是同样的操作。
 简单来说,深度搜素算法就是一条道走到黑,走不动了再回溯回去,选择其他路径,举个例子,对于下面的图,假设从1开始遍历:








用途

深度搜索常用于解决图的遍历问题(尤其是矩阵图如迷宫问题等),比如求解从某一个点到另一个点的最短距离,则只需遍历所有路径,在遍历同时记录路径长度,最后一定能找到最短的距离,但这种方法复杂度较高,因为要遍历完所有结点才能找到。
深度搜索是回溯法的主要方法,沿着一条路一直走,走不通再回溯到上一节点,选择其他路径。

深度搜索模板

int check(参数)
{if(满足条件)return 1;return 0;
}void dfs(int step)
{判断边界if{到达边界时的操作(输出等)}未到边界时尝试每一种可能else{满足check条件 if{标记继续下一步 : dfs(step+1)恢复初始状态}};
}

深度搜索经典例题:【n-皇后问题】

n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

现在给定整数 n,请你输出所有的满足条件的棋子摆法。
输入格式
共一行,包含整数 n。
输出格式
每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。每个方案输出完成后,输出一个空行。注意:行末不能有多余空格。输出方案的顺序任意,只要不重复且没有遗漏即可。
数据范围
1≤n≤9
输入样例
4
输出样例
.Q…
…Q
Q…
…Q.

…Q.
Q…
…Q
.Q…

(DFS按行枚举) 时间复杂度 O ( n ! ) O(n!)O(n!)
代码分析

对角线 d g [ u + i ] dg[u+i]dg[u+i],反对角线u d g [ n − u + i ]
udg[n−u+i]udg[n−u+i]中的下标 u + i u+iu+i和 n − u + i n−u+in−u+i 表示的是截距

下面分析中的 ( x , y ) (x,y)(x,y) 相当于上面的 ( u , i ) (u,i)(u,i)
反对角线 y = x + b y=x+by=x+b, 截距 b = y − x b=y−xb=y−x,因为我们要把 b 当做数组下标来用,显然 b 不能是负的,所以我们加上 +n(实际上+n+4,+2n都行),来保证是结果是正的,即 y − x + n y - x + ny−x+n
而对角线 y = − x + b y=−x+by=−x+b, 截距是 b = y + x b=y+xb=y+x,这里截距一定是正的,所以不需要加偏移量
核心目的:找一些合法的下标来表示 d g dgdg 或 u d g udgudg 是否被标记过,所以如果你愿意,你取 u d g [ n + n − u + i ] udg[n+n−u+i]udg[n+n−u+i] 也可以,只要所有 ( u , i ) (u,i)(u,i) 对可以映射过去就行
题目答案

#include<bits/stdc++.h>using namespace std;
const int N = 100;
char g[N][N];  // g[N][N]用来存路径
// bool数组用来判断搜索的下一个位置是否可行
bool col[N],dg[N],udg[N]; // g[N][N]用来存路径
int n;void dfs(int x){// u == n 表示已经搜了n行,故输出这条路径if(x == n){for (int i = 0; i < n; ++i) puts(g[i]); // 等价于cout << g[i] << endl;puts(""); // 换行return;}else{for (int i = 0; i < n; ++i) {// 剪枝(对于不满足要求的点,不再继续往下搜索)// udg[n - u + i],+n是为了保证下标非负if(!col[i] && !dg[x+i] && !udg[n-x+i]){g[x][i] = 'Q';col[i] = dg[x+i] = udg[n-x+i] = true;dfs(x+1);g[x][i] = '.';col[i] = dg[x+i] = udg[n-x+i] = false;// 恢复现场 这步很关键}}}}
int main() {cin>>n;for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {g[i][j] = '.';}}dfs(0);return 0;
}

广度搜索(BFS)

搜索方法

广度搜索,顾名思义,就是更大范围内搜索,与深度搜索不同的是,深度搜索是一次搜索一条路径,一直搜索到走不通为止;而广度搜索是同时搜索所有路径,相当于一层一层地搜索,就好比波浪的扩展一样。此搜索方法跟树的层次遍历类似,因此宽度搜索一般都用队列存储结构。搜索原则:

搜索方法

(1)访问遍历出发顶点,该顶点入队
(2)队列不空,则队头顶点出队;
(3)访问出队顶点所有的未访问邻接点并将其入队;
(4)重复(2)(3),直到队空或者找到目标点
举个例子,还是对下面这个图进行广度遍历:




用途

虽然看似广度搜索一次扩张了很多个点,但实际上任然是一个结点一个结点地搜索,只是它是以层层扩张的方式进行搜索。广度搜索也常用于解决图的遍历,在求一个点到另一个点的最短距离时,广度搜索比深度搜索更有优势,因为广度搜索是层层遍历的,所以一定存在某条路径最先到达目标点,只要找到目标点后就退出,就不用搜索所有点。
 广度搜索也是分支限界法的主要算法(当然,分支限界也可能是广度搜索和宽度搜索的结合)。广度搜索最常解决的问题类型是:求从某一个状态到另一个状态的最小步数,每一个状态对应多个(扩展结点个数)不同的操作。

广度搜索模板

#include<iostream>
#include<queue>
using namespace std;
struct state
{int a,b;//存储相应信息int step;//存储当前结点的步数
};
queue<state>Q;
int bfs(int a,int b,int A,int B)//返回最小步数
{//参数a,b是初始状态,//参数A,B是目标状态判断条件;while(!Q.empty())Q.pop();//清空队列state P;P.a=a;P.b=b;P.step=0;//初始结点Q.push(P);//初始结点入队while(!Q.empty())//队列非空{state head=Q.front();//保存队头Q.pop();//队头出队//以下扩展每个结点的邻接结点*************************state p=head;p.a=...//执行操作p.b=...//执行操作p.step++;//步数加一//判断p.a,p.b是否合法(剪枝处理)if(ok(p.a,p.b)){if(p.a==A&&p.b==B)//判断该状态是否满足目标状态return p.step;//返回步数Q.push(p);//否则入队}//扩展其他结点......//扩展结点结束*************************************}return -1;//不能到达目标状态,返回-1;
}

深度搜索经典例题:【走迷宫——边的权值相同】

给定一个 n ∗ m n*mn∗m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 ( 1 , 1 ) (1, 1)(1,1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 ( n , m ) (n, m)(n,m) 处,至少需要移动多少次。
据保证 ( 1 , 1 ) (1, 1)(1,1) 处和 ( n , m ) (n, m)(n,m) 处的数字为 0,且一定至少存在一条通路。
输入格式
第一行包含两个整数n和m。
接下来n行,每行包含m个整数(0或1),表示完整的二维数组迷宫。
输出格式
输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围
1≤n,m≤100
输入样例
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例
8
答案解析

#include<bits/stdc++.h>using namespace std;
const int N = 110;
int n,m;
int g[N][N],d[N][N];  // g记录迷宫,d记录该位置与起始位置的距离
typedef pair<int,int> PII;
queue<PII> q;int bfs(){int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};q.push({0,0}); //从第一个元素开始访问d[0][0] = 0;while(!q.empty()){auto t = q.front();  q.pop();for(int i = 0;i < 4;i++){int x = t.first+dx[i] , y = t.second+dy[i];if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && !d[x][y]){d[x][y] = d[t.first][t.second]+1;q.push({x,y});}}}return d[n-1][m-1];
}int main() {cin>>n>>m;for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin>>g[i][j];cout<<bfs()<<endl;return 0;
}

来源

深度搜索(DFS)和广度搜索(BFS)——1
深度搜索(DFS)和广度搜索(BFS)——2

【算法】深度搜索(DFS) 和 广度搜索(BFS)相关推荐

  1. 深度搜索(DFS)和广度搜索(BFS)

    深度搜索(DFS) 一.搜索方法:  沿出发顶点的第一条路径尽量深入,遍历路径上所有顶点:然后退回到该顶点,搜索其它路径,直到以该顶点为始点的所有路径的顶点都被访问,深度搜索算法是递归算法,因为对于没 ...

  2. 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  3. 【蓝桥杯】2015决赛A组 5 穿越雷区(深度优先搜索dfs、广度优先搜索bfs)

    历届试题 穿越雷区 问题描述 X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废. 某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征), ...

  4. 【数据结构与算法】2.深度优先搜索DFS、广度优先搜索BFS

    原文链接:https://blog.csdn.net/qq_41681241/article/details/81432634 总结 一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的 ...

  5. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  6. 深度优先搜索(DFS)和广度优先搜索(BFS)探究

    附BFS解题代码: #include<iostream> #include<queue> using namespace std;char room[23][23]; int ...

  7. 深度搜索(DFS),一种用于遍历和搜索的算法

    先上百度对深度搜索的定义: 如果上边的定义没有理解,那么可以这样认为:深度搜索就是一种试探性的算法,例如你在一个十字路口想要去到某地,但是你又不认识具体的路(并且你不善言辞,万事不求人),那么你只能先 ...

  8. 数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)

    文章目录 前言 邻接矩阵和邻接表 深度优先搜索(dfs) 宽度(广度)优先搜索(bfs) 总结与比较 前言 在有向图和无向图中,如果节点之间无权值或者权值相等,那么dfs和bfs时常出现在日常算法中. ...

  9. 深度搜索和广度搜索领接表实现_算法基础04-深度优先搜索、广度优先搜索、二分查找、贪心算法...

    深度优先搜索DFS.广度优先搜索BFS 比较 拿谚语打比方的话,深度优先搜索可以比作打破砂锅问到底.不撞南墙不回头:广度优先搜索则对应广撒网,多敛鱼 两者没有绝对的优劣之分,只是适用场景不同 当解决方 ...

最新文章

  1. JVM技术周报第2期
  2. DISCUZ X2更换域名注意事项
  3. 数字后端——时序验证
  4. python消息队列模块_day43-python消息队列二-queue模块
  5. 虚拟时代将至:环绕计算才是未来
  6. [BZOJ2038] [2009国家集训队] 小Z的袜子(hose) (莫队)
  7. 质疑“扩版=质量下降”——以《中国农学通报》和《安徽农业科学》为例
  8. 结构-行为-样式-有趣的函数
  9. 微信飞机大战游戏开发
  10. Day3:MVP+ButterKnife+Dagger2的使用
  11. java 调用nc查询引擎_用友NC系统查询引擎应用心得
  12. CPU卡FM1208发卡操作流程(不带密钥验证)
  13. java awt canvas_JAVA.AWT.CANVAS使用
  14. 把手机当作电脑显示器指导参考
  15. diag()函数功能
  16. Python 计算EMA(指数移动平均线)
  17. 《人性的弱点》总结之一 --- 人际交往的基本技巧
  18. python分别计算100以内(含100)奇数和偶数的和
  19. 关于 Burte Force
  20. html video 加广告,视频加入广告,如何在视频中插入一段广告视频,视频加广告的方法...

热门文章

  1. 利用BrainTree自定义UI绑定信用卡及Paypal
  2. Dango Web 开发指南 学习笔记 3
  3. 如何破解百度文库的防复制功能
  4. 分布式Ruby解决之道 - DRb
  5. 15.A Syntactic Neural Model for General-Purpose Code Generation
  6. spyder 清屏操作
  7. 认识计算机课件小游戏,2013年小学信息技术教案《认识计算机二》教案
  8. UART/USB UART/USB你必须知道的
  9. matlab水汽计算公式,[转载]matlab 解方程组
  10. 天王星技术社区在成都举行《联盟链趋势和应用》交流会