文章目录
- 前言
- 一、DFS是什么?
- 二、DFS的使用步骤?
- 三、N皇后问题
- 总结
前言
离上次的博客已经有5天了,虽然没人关注我,但是我还是想说:我没有在偷懒,只是最近复习的知识,我觉得要自己领悟透彻才来写博客,更新不容易,能否给我点个关注。
回归正题:今天写的是DFS(深度优先)和BFS(广度优先),想必大家对这个肯定不陌生,我们在写题的时候,会遇到很多这种类型的题目,还能扩展到树与图的应用(树的DFS和BFS)。
一、DFS是什么?
DFS(深度优先搜索算法):一种用于遍历或者树或者图的算法,是一种递归程序,不断递归达到无法在到达的点,简单点来说:一条路一直走,走到没有路后就原路返回,重新选择另一条 dfs(step + 1)。
DFS = 暴搜 + 回溯算法 + 剪枝(大多数是这样)。DFS需要回溯算法,其他算法也需要回溯算法,两种是一种调用关系。
暴搜:一条路走到黑(直接递归走到底)
回溯:DFS 开启另一条路则需要回溯,如果暴搜那条路找不到答案就要回溯走另外一条道路。
剪枝:如果明确接下来的搜索找不到答案或者不是最优解,就不再进行搜索并对路径进行回溯,从而达到减少问题搜索规模的目的。
图解:(箭头的遍历方式)1 -> 2 -> 4 -> 8 -> 4 -> 2 -> 5 -> 9 - > 5 -> 2 -> 1 -> 3 -> 6 -> 10
-> 6 -> 3 -> 7。
二、DFS的使用步骤
void dfs(int step){ //step搜索的路径步骤
判断边界问题{
进行操作(如搜索完,并找到答案)
}
尝试每一种可以走的路径{
check() return ;//剪枝
标记该状态已经走到
继续下一步搜索 DFS(step + 1)
回溯(回到最开始的状态)
}
}
三、N皇后问题
n皇后问题:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 20;
int n;
char g[N][N]; //n皇后的表格
bool col[N], dg[N], udg[N]; //状态,表示行、对角线、逆对角线放了皇后。
void dfs(int u){ //表示第几行
if(u == n){ //边界问题,如果u == n,说明皇后已经全部放好
for(int i = 0; i < n; i ++) puts(g[i]);
puts(" ");
return ;
}
//n行放皇后
for(int i = 0; i < n; i ++){
if(!col[i] && !dg[u + i] && !udg[n - u + i]){ //如果没放皇后
col[i] = dg[u + i] = udg[n - u + i] = true;
g[u][i] = 'Q';
//进行下一步
dfs(u + 1);
//回溯
col[i] = dg[u + i] = udg[n - u + i] = false;
g[u][i] = '.';
}
}
}
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;
}
总结
这只是浅谈一下DFS,并DFS算法还有很多方面,我会在后面慢慢更新博客讲解,下一篇讲的是BFS(广度优先算法)和DFS两个都是应用与图与树的知识。