層序遍歷 求解迷宮問題

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章