层序遍历 求解迷宫问题

求由(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); 
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值