bfs就是广度优先搜索,与深度优先搜索有类似之处也有不同之处。
深度优先搜索是不撞南墙不回头的莽夫。
而广度优先搜索则像高塔一样稳健。
所以说广度优先搜索总是能找到一个问题的最优解,但它没有深搜那么莽夫,所以广搜所要花费的时间往往比深搜要久。
bfs要先建立一个队列
struct node
{
int ;//至少两个,一个表示数据,一个表示数据所在的位置。
};
用这个结构体来表示每一步与每一步所在的位置。
dfs考虑的是当先该怎么做并用递归写出下一次,而bfs考虑的是下一次有几种做法。
我这里给出dfs的文章做对比dfs原理
为了直观的显现出bfs与dfs的区别,我们用bfs来解我之前在dfs上的原题:
B先生在一个迷宫里迷路了,他需要A先生的救助,A先生也不知道怎么走,所以他只能一步一步试。
现在编程来帮A先生解救B先生。
m,n代表迷宫的长与宽。
m行,n列0或1.其中0代表路,1代表障碍。
出发坐标(x,y)与目标坐标(sx,sy)
最短步数。
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
7
#include
struct node
{
int x,y,s;//x,y为坐标,s为步数。
};
truct node que[2501];//地图
int a[51][51]={
0},book[51][51]={
0};
int next[4][2]={
{
0,1},{
1,0},{
0,-1},{
-1,0}};//方向
int head,tail;
int i,j,k,m,n,sx,sy,p,q,tx,ty,flag;
scanf("%d%d",&n,&m);//初始化地图
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
scanf("%d",&a[i][j]);
scanf("%d%d%d%d",&sx,&sy,&p,&q);//队列初始化
head=1; //其他值的初始化
tail=1;
que[tail].x=sx;
que[tail].y=sy;
que[tail].s=0;
tail++;
book[sx][sy]=1;
flag=0;
如果用dfs,我们就用一个dfs函数来模拟每一步。
void dfs(int x,int y,int step)
{
int next[4][2]={
{
0,1},{
1,0},{
0,-1},{
-1,0}};
int i,nx,ny;
if(x==p&&y==q){
if(step<min)
min=step;
return;
}
for(i=0;i<=3;++i){
nx=x+next[i][0];
ny=y+next[i][1];
if(nx<1||ny<1||nx>n||ny>m)
continue;
if(a[nx][ny]==0&&book[nx][ny]==0){
book[nx][ny]=1;
dfs(nx,ny,step+1);
book[nx][ny]=0;
}
}
return;
}
如果用bfs则:
1. 首先判断这个地方走没走过 *head
2. 列举四分方向
for(k=0;k<=3;++k){
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0){
//这里判断这一步是否走过
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].s=que[head].s+1;
tail++;
}
3.如果找到目的地了flag=1;
并break;
if(tx==p&&ty==q){
flag=1;
break;
}
4.如果flag=1;
则代表这里条路已经走完了,则进行下一次尝试head++
while(head<tail){
for(k=0;k<=3;++k){
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0){
//和dfs一样乱七八糟的判断
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].s=que[head].s+1;
tail++;
}
if(tx==p&&ty==q){
flag=1;
break;
}
}
if(flag==1)
break;
head++;
}
在进行完这些步骤之后。最少的步数就模拟出来了。
接下来只需要进行一个简单的printf
即可。
#include
struct node
{
int x,y,s;//x,y为坐标,s为步数。
};
int main()
{
struct node que[2501];//地图
int a[51][51]={
0},book[51][51]={
0};
int next[4][2]={
{
0,1},{
1,0},{
0,-1},{
-1,0}};//方向
int head,tail;
int i,j,k,m,n,sx,sy,p,q,tx,ty,flag;
scanf("%d%d",&n,&m);//初始化地图
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
scanf("%d",&a[i][j]);
scanf("%d%d%d%d",&sx,&sy,&p,&q);//队列初始化
head=1;
tail=1;
que[tail].x=sx;
que[tail].y=sy;
que[tail].s=0;
tail++;
book[sx][sy]=1;
flag=0;
while(head<tail){
for(k=0;k<=3;++k){
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue;
if(a[tx][ty]==0&&book[tx][ty]==0){
//和dfs一样乱七八糟的判断
book[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].s=que[head].s+1;
tail++;
}
if(tx==p&&ty==q){
flag=1;
break;
}
}
if(flag==1)
break;
head++;
}
printf("%d",que[tail-1].s);
return 0;
}