DFS BFS 路径记录的总结

最近还是学了一些东西的

关于搜索本身没有什么难以理解的东西,但是这个路径晦朔真的是让我头疼了一整天,感谢峰神提点

现在总结如下


DFS路径记录

首先,DFS一般是用递归实现的,在每次递归前我们在结构体数组中记录一下当前的坐标,然后再进行递归,在找到目标的时候,恰好我们找到了一组坐标点,进而实现了路径的记录

以下是简单的代码解析

#include"iostream"
#include"cstdio"
#include"cstdlib"
using namespace std;


struct node                 //记录路径点信息的结构体
{
int x;
int y;
};


typedef struct node point;


point p[100];


int top=1;


char map[100][100];
int book[100][100];
int n,m;
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int bx,by;
int ex,ey;
int sum=0;


void dfs(int x,int y,int step)
{
int dx,dy;
for(int i=0;i<=3;i++)
{
dx=x+next[i][0];
dy=y+next[i][1];
if(dx==ex&&dy==ey)
{
for(int i=1;i<top;i++)                       //找到目标,依次输出
{
printf("(%d,%d)\n",p[i].x,p[i].y);
}
printf("(%d,%d)\n",ex,ey);
sum=step+1;
}
if(dx<1||dx>n||dy<1||dy>m||map[dx][dy]=='#')
{
continue;
}
else
{
if(book[dx][dy]==0&&map[dx][dy]=='.')
{
book[dx][dy]=1;
p[top].x=dx;                //满足条件,加入记录数组
p[top].y=dy;
top++;
dfs(dx,dy,step+1);
book[dx][dy]=0;
top--;                        //开始晦朔,递减记录数组
}
}
}
}


int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
}
}
cin>>bx>>by>>ex>>ey;
book[bx][by]=1;
p[top].x=bx;
p[top].y=by;
top++;
dfs(bx,by,0);
cout<<sum<<endl;
return 0;
}





BFS  路径记录

BFS的路径记录想起来确实花了我不少时间,但是我还是想到了解决办法,不知道算不算好的,但是总归是自己的思想的结晶

我的方法的核心就是在结构体中加入一个past变量,用来记录被访问的点的前驱在BFS队列中的编号,下次就不需要对队列进行多余的处理

我们可以直接引用past变量直接访问该点的前驱


以下是代码的实例和部分注释

#include"iostream"
#include"cstdio"
#include"cstdlib" 
using namespace std;


struct node
{
int x;
int y;
int past;
int len;
};


typedef struct node point;


point queue[100];
point stack[100];
int head;
int tail;


char map[100][100];
int book[100][100];
int n,m;
int sum=0;
int bx,by;
int ex,ey;
int dx,dy;
int next[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int top=0;


int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
}
}
cin>>bx>>by>>ex>>ey;
head=tail=1;
queue[1].x=bx;
queue[1].y=by;
queue[1].past=1;
queue[1].len=0;
book[bx][by]=1;
tail++;
while(head<tail)
{
for(int i=0;i<=3;i++)
{
dx=queue[head].x+next[i][0];
dy=queue[head].y+next[i][1];
if(dx==ex&&dy==ey)
{
for(int i=1;head!=1;i++)
{
stack[i].x=queue[head].x;
stack[i].y=queue[head].y;
head=queue[head].past;                    //引用past变量进行队列的回溯
}
top=queue[tail-1].len;
sum=queue[tail-1].len+1;
head=tail;
break;
}
if(dx<1||dx>n||dy<1||dy>m||map[dx][dy]=='#')
{
continue;
}
else
{
if(book[dx][dy]==0&&map[dx][dy]=='.')
{
book[dx][dy]=1;
queue[tail].x=dx;
queue[tail].y=dy;
queue[tail].len=queue[head].len+1;
queue[tail].past=head;
tail++;
}
}
}
head++;
}
printf("(%d,%d)\n",bx,by);
for(int i=top;i>=1;i--)
{
printf("(%d,%d)\n",stack[i].x,stack[i].y);
}
printf("(%d,%d)\n",ex,ey);
cout<<sum<<endl;
return 0;
}


  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值