什么是深度优先搜索
- 搜素方法
沿出发顶点的第一条路径尽量深入,遍历该路径上的所有点,然后退回到该顶点路径的上一个分叉点,搜索其他路径,直到以该顶点为始点的所有路径的点都被访问,即不撞南墙不回头。 - 涉及知识
递归和回溯
用途
- 深度搜索常用来解决图的遍历,迷宫的最短路径。
- 回溯法是深度优先搜索的主要方法,沿着一条路一直走,走不通再回溯上一节点,选择其他路径。
图的搜索
#include<stdio.h>
#define MAX 99999
int book[101],sum,n,e[101][101];
void dfs(int cur){
int i;
printf("%d ",cur);
sum++;
if(sum==n)
return;
for(i=1;i<=n;i++){
if(e[cur][i]==1&&book[i]==0){
book[i]=1;
dfs(i);
}
}
return;
}
int main(){
int m,a,b,i,j;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
e[i][j]=MAX;
}
}
for(i=1;i<=m;i++){
scanf("%d %d",&a,&b);
e[a][b]=1;
e[b][a]=1;
}
book[1]=1;
dfs(1);
return 0;
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4da25891d74988e54780181b3cea5eec.png)
例题
- 以一个迷宫问题来举例,以一个二维数组来存储迷宫的信息,1代表墙,0表示可以走,算出从起始点到结束点要走的最少步数
- 可以用一个数组做标记表示该点走过没有,但是回溯时要记得解除标记,因为在新的那一种即新的一条路时,那个点并未走过
#include<stdio.h>
int n,m,endx,endy,min=9999;
int a[51][51],book[51][51];
void dfs(int x,int y,int step){
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int ty,tx,k;
if(x==endx&&y==endy)
{
if(step<min)
min=step;
return;
}
for(k=0;k<=3;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>m||ty<1||ty>n)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)
{
book[tx][ty]=1;
dfs(tx,ty,step+1);
book[tx][ty]=0;
}
}
return;
}
int main(){
int i,j,startx,starty;
scanf("%d %d",&m,&n);
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&startx,&starty,&endx,&endy);
book[startx][starty]=1;
dfs(startx,starty,0);
printf("%d",min);
return 0;
}