深度优先搜索认识
深度优先搜索(DFS)是一种用于遍历或搜索图和树的算法。它从起始节点开始,沿着路径尽可能深地探索,直到达到目标节点或无法继续为止,然后回溯到最近的一个未探索节点,继续探索。
我们平常听到的迷宫问题就是深度优先搜索
基本步骤:
我们可以举个例子解释深度优先搜索(以下简称DFS,深搜),假设小A同学从迷宫的一个点出发,在真身动之前会派出分身,分身一般是探索前面有没有路的,假设分身按照前后左右的顺序依次探索,如果前面没路,那么探索左面,如果左面没路,那么探索右面,假设右面有路就往右面走,但有时候也会遇到最后堵死的情况,那么就只能顺着标记往回走了
搜索策略
- 通过选择节点扩展的顺序来定义搜索策略
- 根据以下维度评估策略:
- 完整性(完备性): 如果存在,它是否总能找到解决方案?
- 时间复杂性(时间复杂度): 生成的节点数
- 空间复杂性(空间复杂度) : 内存中的最大节点数
- 最优性(最优性): 它总是找到成本最低的解决方案吗?
- 时间和空间复杂性是根据
- b: maximum branching factor of the search tree搜索树的最大分支因子—分支因子
- d: depth of the least-cost solution—最浅的目标节点的深度
- m: maximum depth of the state space状态空间的最大深度(可以是 ∞ ∞ ∞)—最大深度
接下来是代码实现:
例题:
数水坑
题目描述
由于近期的降雨,雨水汇集在小码君的田地不同的地方。我们用一个 N×M(1≤N≤100,1≤M≤100) 的网格图表示。每个网格中有水(W
) 或是旱地(.
)。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。小码君想弄清楚他的田地已经形成了多少水坑。给出小码君田地的示意图,确定当中有多少水坑。
提示
样例说明:
样例中水坑位于左上角,左下角以及最右边,一共有 3 个水坑。如图所示:
输入格式
输入第 1 行:两个空格隔开的整数:N 和 M。
第 2 行到第 N+1 行:每行 M 个字符,每个字符是 W
或 .
,它们表示网格图中的一排。字符之间没有空格。
输出格式
输出一行,表示水坑的数量。
样例组输入#1
10 12 W........WW. .WWW.....WWW ....WW...WW. .........WW. .........W.. ..W......W.. .W.W.....WW. W.W.W.....W. .W.W......W. ..W.......W.
样例组输出#1
3
代码实现:
#include<bits/stdc++.h>
using namespace std;
char a[150][150];
int n,m,s;
int dx[]={0,0,-1,1,-1,1,-1,1};
int dy[]={1,-1,0,0,1,-1,-1,1};
void dfs(int x,int y){
a[x][y]='.';
for(int i=0;i<8;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]=='W'){
dfs(xx,yy);
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='W'){
dfs(i,j);//把这个w为起点的所有w全部变成旱地
s++;
}
}
}
cout<<s;
return 0;
}
下节预告:
深搜并不是解决迷宫问题最有效的办法,那么接下啦我们就来讲一下比深搜更快的广度优先搜索(简称广搜,BFS),广度优先搜索预计于2024.7.8号更新,敬请期待!!!
---------------------------------------------------------------------------------------------------------------------------------