目录
前言:
广度优先遍历(Breath First Search)作为一种相对DFS算法来说,更加适合迷宫算法的算法,尤其在最短路径求解时有着自己独特的用法;其实将BFS和DFS放到一起来看,其实不管是BFS换上DFS,都是对线性表的操作,只不过DFS是利用栈的特性写的回溯函数而已,而BFS是利用队列的特性写的拓展函数而已。
(不是很懂DFS算法的兄弟们可以看我上一篇博客)
数据结构篇(二):DFS和BFS算法的分析与总结之DFS篇_靳小锅er的博客-CSDN博客_bfs算法
广度优先遍历(BFS)
其实本质上广度优先遍历就是不断的退队和入队;核心算法本质:将起点入队,队首结点可拓展的点入队,如果没有可拓展的点,将队首结点出队,重复该步骤,直到到达目标位置或者队列为空。
一、图形讲解
1.将A移入队列
2.将A移出队列,将相邻节点依次加入队列
- 将B移出队列,如果B有邻接点且未被访问过,将其依次压入队列 。
- 将C移出队列,如果C有邻接点且未被访问过,将其依次压入队列 。
- 将D移出队列,如果D有邻接点且未被访问过,将其依次压入队列 。
- 将F移出队列,将H,G入队。
3.将C,B入队,结束遍历
二、例题详解
如何用代码表示输出迷宫最短路径
三、代码展示
#include<stdio.h>
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;
}
总结:
其实我们看完BFS和DFS算法后会发现,这其实时利用了队列和栈这两种存储结构的特殊的存储方式,比如栈的先进后厨,队列的先进先出。