DFS(深度优先搜索)
最简单的搜索包含 DFS 和 BFS,他们分别有着下面不同的用途和区别:
区别于用途:
1.BFS是用来搜索最短径路的解是比较合适的,比如求最少步数的解,最少交换次数的解,因为BFS搜索过程中遇到的解一定是离根最近的,所以遇到一个解,一定就是最优解,此时搜索算法可以终止。这个时候不适宜使用DFS,因为DFS搜索到的解不一定是离根最近的,只有全局搜索完毕,才能从所有解中找出离根的最近的解。(当然这个DFS的不足,可以使用迭代加深搜索ID-DFS去弥补)
2.空间优劣上,DFS是有优势的,DFS不需要保存搜索过程中的状态,而BFS在搜索过程中需要保存搜索过的状态,而且一般情况需要一个队列来记录。
3.DFS适合搜索全部的解,因为要搜索全部的解,那么BFS搜索过程中,遇到离根最近的解,并没有什么用,也必须遍历完整棵搜索树,DFS搜索也会搜索全部,但是相比DFS不用记录过多信息,所以搜素全部解的问题,DFS显然更加合适。
下面是DFS代码的基本实现与模板
DFS可以用递归实现,其基本模板是:
void dfs()//参数用来表示状态
{
if(到达终点状态)
{
...//根据题意添加
return;
}
if(越界或者是不合法状态)
return;
if(特殊状态)//剪枝
return ;
for(扩展方式)
{
if(扩展方式所达到状态合法)
{
修改操作;//根据题意来添加
标记;
dfs();
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
}
}
}
八皇后代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=14;
int ans[maxn],check[3][28];
int tot=0,n;
void dfs(int line)
{
if(line>n){
tot++;
if(tot<=3){
for(int i=1;i<=n;++i)
cout<<ans[i]<<" ";
cout<<endl;
return;
}
else return;
}
for(int i=1; i<=n; ++i){
if(!check[0][i]&&!check[1][line+i]&&!check[2][n+line-i]){
ans[line]=i;
check[0][i]=1;
check[1][line+i]=1;
check[2][n+line-i]=1;
dfs(line+1);
check[0][i]=0;
check[1][line+i]=0;
check[2][n+line-i]=0;
}
}
}
int main()
{
memset(check,0,sizeof(check));
cin>>n;
dfs(1);
cout<<tot<<endl;
return 0;
}