棧的應用Ⅱ--迷宮問題
阿新 • • 發佈:2019-01-06
利用棧解決迷宮問題
如圖,定義起點和終點,求出從起點到終點的路徑。
首先迷宮分為兩種格子,一種是空白格子視為可移動格子。一種黑色格子,視為牆壁,不可移動。接著考慮如何表示移動的方向,可以使用識別符號標記移動的方向,這裡可以使用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深度優先遍歷,只要找到周圍一個能訪問的節點,就進行訪問,再訪問該節點的周圍節點,找到即訪問,一路走到黑的趕腳。