深度优先搜索

什么是深度优先搜索

  1. 搜素方法
    沿出发顶点的第一条路径尽量深入,遍历该路径上的所有点,然后退回到该顶点路径的上一个分叉点,搜索其他路径,直到以该顶点为始点的所有路径的点都被访问,即不撞南墙不回头。
  2. 涉及知识
    递归和回溯

用途

  • 深度搜索常用来解决图的遍历,迷宫的最短路径。
  • 回溯法是深度优先搜索的主要方法,沿着一条路一直走,走不通再回溯上一节点,选择其他路径。

图的搜索

#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;
} 

在这里插入图片描述

例题

  • 以一个迷宫问题来举例,以一个二维数组来存储迷宫的信息,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);//开始时步数为0
 printf("%d",min);
 return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值