1. 程式人生 > >棧的應用Ⅱ--迷宮問題

棧的應用Ⅱ--迷宮問題

利用棧解決迷宮問題

如圖,定義起點和終點,求出從起點到終點的路徑。
maze
首先迷宮分為兩種格子,一種是空白格子視為可移動格子。一種黑色格子,視為牆壁,不可移動。接著考慮如何表示移動的方向,可以使用識別符號標記移動的方向,這裡可以使用0,1,2,3代表上右下左四個方向。走過的格子也要標記為已考察過。考察到終點視為成功。

過程:
①將起點座標入棧,
②根據棧頂元素0,1,2,3(上右下左)四個方向進行遍歷,發現有格子不是牆,並且還未考察過,則將其入棧。
③重複②直到發現終點,或者0,1,2,3四個方向都無法移動。回溯,將棧頂元素退棧,繼續②操作。

將牆體置為1,空白格子置為0。
這裡寫圖片描述

#define M 6
#define N 6
#define MaxSize 80

int mg[M+2][N+2] = {
{1,1,1,1,1,1,1,1},
{1,0,0,0,1,0,0,1},
{1,0,1,0,1,1,0,1},
{1,0,1,1,0,0,0,1},
{1,0,1,0,0,1,0,1},
{1,0,0,0,1,1,0,1},
{1,0,1,0,1,0,0,1},
{1,1,1,1,1,1,1,1}
};

typedef struct
{
    int x;
    int y;
    int di;               //定義在座標時本次移動方向
}Node;

typedef struct
{
    Node data[MaxSize];
    int top;
}SqStack;

bool MgPath(int xi,int yi,int xe,int ye)
{
    int x,y,k,di,find;
    SqStack s;
    s.top = -1;
    s.top++;
    s.data[s.top].x = xi;
    s.data[s.top].y = yi;
    s.data[s.top].di = -1;       //將訪問方向置為-1,即周圍座標都未訪問
    mg[xi][yi] = -1;             //起始點正在訪問,置為-1以後就不再訪問
    while(s.top>-1)
    {
        x = s.data[s.top].x;      
        y = s.data[s.top].y;
        di = s.data[s.top].di;      //將棧頂元素取出
        if(x==xe&&y==ye)            //如果棧頂元素即為終點
        {
            printf("迷宮路徑如下:\n");
                for(k=0;k<=s.top;k++)     //對棧中元素自底向上訪問
            {
                printf("\t(%d,%d)",s.data[k].x,s.data[k].y);
                if((k+1)%5==0)
                    printf("\n");
            }
            printf("\n");
            return true;
        }
        find = 0;                 
        while(di<4&&find==0)   //迴圈直到找到四周能訪問的座標,或者四周座標都無法訪問
        {
            di++;         //對下一個方向的座標進行訪問
            switch(di)
            {
                case 0:
                    x = s.data[s.top].x-1;
                    y = s.data[s.top].y;
                    break;
                case 1:
                    x = s.data[s.top].x;
                    y = s.data[s.top].y+1;
                    break;
                case 2:
                    x = s.data[s.top].x+1;
                    y = s.data[s.top].y;
                    break;
                case 3:
                    x = s.data[s.top].x;
                    y = s.data[s.top].y-1;
                    break;              
            }
            if(mg[x][y]==0)       //若該座標為0,即為空格並且未被訪問
                find = 1;         //將訪問到座標置為1
        }
        if(find==1)            //將訪問的座標入棧
        {
            s.data[s.top].di = di;
            s.top++;
            s.data[s.top].x = x;
            s.data[s.top].y = y;
            s.data[s.top].di = -1;
            ma[x][y] = -1;        //訪問過的座標置為-1
        }
        else         //若四周未找到可訪問座標,則進行回溯
        {
            //mg[s.data[s.top].x][s.data[s.top].y] = 0;
            s.top--;
        }
    }
    return false;
}

用棧實現迷宮問題,對應的是DFS深度優先遍歷,只要找到周圍一個能訪問的節點,就進行訪問,再訪問該節點的周圍節點,找到即訪問,一路走到黑的趕腳。