深度优先搜索(DFS)
深搜的过程:从根进入,向下走,走到底,向上走,即绕树兜圈,最后从根退出
深搜的实现:深搜是通过系统栈实现的,因为栈满足先进后出的性质,所以当树的子树被全部搜完后才会回到该树。(后面的BFS使用队列实现的,因为队列满足先进先出的性质,适合于BFS的逐层遍历,这个在BFS文章中会提到。)DFS中递归调用的过程,系统自动通过栈去维护函数的状态空间。系统栈记录函数的返回地址,局部变量,参数传递等。向下走,压栈;向上走,弹栈。
深搜的模板
int dfs(int t)
{
if(满足输出条件)
{
输出解;
}
else
{
for(int i=1;i<=尝试方法数;i++)
if(满足进一步搜索条件)
{
为进一步搜索所需要的状态打上标记;
bfs(t+1);
恢复到打标记前的状态;//也就是说的{回溯一步}
}
}
}
多叉树的DFS简单模板。
深搜的计算:触碰节点的时机:1.入 2.下 3.回 4.离
void dfs(int u, int fa){
// printf("进入%d\n",u);
for(auto v : e[u]){
if(v==fa) continue;
// printf("下走%d\n",u);
dfs(v, u);
// printf("上回%d\n",u);
}
// printf("离开%d\n",u);
}
同理二叉树触碰点的时机分为:先、中、后。在这三个触碰的时机进行操作也就是先序遍历,中序遍历和后序遍历
void dfs(int u, int fa){
// printf("先%d\n",u);
dfs(2 * u);
// printf("中%d\n",u);
dfs(2 * u + 1);
// printf("后%d\n",u);
}
Awing842
cpp
#include<iostream>
using namespace std;
const int N = 10;
int path[N],n;
bool st[N];
void bfs(int u){
if(u == n){
for(int i = 0;i < n;i ++ ) cout << path[i] << " ";
puts("");
return;
}
for(int i = 1;i <= n;i ++ ){
if(!st[i]){
path[u] = i;
st[i] = true;
bfs(u + 1);
st[i] = false; //恢复现场
}
}
}
int main(){
cin >> n;
bfs(0);
return 0;
}
八皇后
cpp
//第一种搜索顺序
#include<iostream>
using namespace std;
const int N = 10;
int n;
bool col[N],dg[2 * N],udg[2 * N];
char g[N][N];
void dfs(int u){
if(u == n){
for(int i = 0;i < n;i ++ ){
for(int j = 0;j < n;j ++ ){
cout << g[i][j];
}
puts("");
}
puts("");
return;
}
for(int i = 0;i < n;i ++ ){
if(!col[i] && !dg[u + i] && !udg[n - u + i]){
g[u][i] = 'Q';
col[i] = dg[u + i] = udg[n - u + i] = true;
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;
}
//第二种搜索顺序
#include<iostream>
using namespace std;
const int N = 110;
bool row[N],col[N],dg[N],udg[N];
char g[N][N];
int n;
void dfs(int x,int y,int s){
if(s > n) return;
if(y == n) y = 0,x ++ ;
if(x == n){
if(s == n){
for(int i = 0;i < n;i ++ ){
for(int j = 0;j < n;j ++ ){
cout << g[i][j];
}
puts("");
}
puts("");
}
return;
}
g[x][y] = '.';
dfs(x,y + 1,s);
if(!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]){
g[x][y] = 'Q';
row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;
dfs(x,y + 1,s + 1);
row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;
g[x][y] = '.';
}
}
int main(){
cin >> n;
dfs(0,0,0);
return 0;
}