文章目录
前言
离上次的博客已经有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两个都是应用与图与树的知识。
BFS的链接: BFS(广度优先算法)_1234_6的博客-CSDN博客