求由(1,1)到终点的最短步数,并输出对应的路径。
1.利用层序遍历,不断扩展延伸。
2.用队列存储。存储父亲节点,找其所有的儿子节点。然后父节点出队,儿子节点变为新父节点,然后找新父节点的所有儿子节点,以此类推。
3.用数组实现队列。
/*
层序遍历实现广度优先搜索。
*/
#include"stdio.h"
#include"string.h"
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右,下,左,上。
int a[50][50];
int book[50][50];
struct Node
{
int x;
int y;
int step;//步数
int parents;
};
struct Node queue[2501];
int main()
{
int head=1;//指向父节点
int rear=1;//rear指向最后一个元素的下一位置
int start_x,start_y;//起点坐标设置为(1,1)
int flag=0;//flag=0没有找到,flag=1找到出口。
int n,m;//地图的行和列
int p,q; //地图出口
int i,j;
int next_x,next_y;
scanf("%d %d",&n,&m );//scanf("%d,%d",&n,&m )控制台输入方式 1,2 scanf("%d %d",&n,&m )控制台输入方式 1 2
for(i=0;i<50;i++)//清空数组
{
for(j=0;j<50;j++)
{
book[i][j]=0;
a[i][j]= 0;
}
}
for(i=1;i<=n;i++)//地图输入,从1开始符合习惯。
{
for(j=1;j<=m ;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&start_x,&start_y,&p,&q);
queue[head].x=start_x;//起点坐标入队
queue[head].y=start_y;
queue[head].step=0;
book[start_x][start_y]=1;//这行别忘了讲起点做入队标记 ,否则会重复到起点1,1。无限次遍历。
rear++; //不要忘记这句,否则会把起点覆盖。而且head==tial,进不去循环。
while(head <rear) //全部出队时,队列空,代表尝试了所有可能的情况
{
for(i=0;i<=3;i++)
{
next_x=queue[head].x+next[i][0];
next_y=queue[head].y+next[i][1];
if(next_x <1||next_x>n||next_y <1||next_y>m)//越界判断不要忘记否则会跳不出循环
continue;//越界元素不入队
if(a[next_x][next_y]==0&&book[next_x][next_y]==0)//入队条件判断:不是障碍物,未曾入队。
{ book[next_x][next_y]=1;//标记坐标(next_x,nexty)入队
queue[rear].x=next_x;//入队
queue[rear].y=next_y;
queue[rear].step=queue[head].step+1;//子节点(此层)为父节点(是上层)步数加一
queue[rear].parents =head;//保存其父节点位置。
rear++;//rear++和 queue[rear].step=queue[head].step+1的次序不能变,否则就会出错。
}
if(next_x==p&&next_y==q)//与递归不同,层序遍历,最先找到出口的坐标,停止往下层拓展时,步数就是最短的。
{
flag=1;
break;
}
}
if(flag==1)
{
break;
}
head++;//四个方向全部尝试完毕,父节点出队
}
printf("找到出口的步数是%d\n",queue[rear-1].step);//rear-1是最后一个入队的元素的位置。
int position;//保存父节点位置
position=rear-1;
printf("走出迷宫的最短轨迹是:(%d %d)<----",queue[position].x,queue[position].y);
while(queue[position].x!=start_x&&queue[position].y!=start_y)
{
position=queue[position].parents;//滑动更新父节点位置 ,滑动窗口思想
printf("(%d %d)<----",queue[position].x,queue[position].y);
}
printf("(%d %d)",start_x,start_y);
}