用棧解決基本的迷宮問題C/C++
1、問題描述:設定迷宮為m*n的二維數組,起點座標為(1,1),中點座標為(m,n),0為通路,1為死路,為防止數組越界將四周設定邊界1,即數組變為(m+2)*(n+2)數組,迷宮如下....
迷宮
| 1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
| 1 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
| 1 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
| 1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
| 1 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
| 1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
| 1 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
| 1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
2、求解思路:
2.1、用數組對迷宮進行定義
#define m 6#define n 8int maze[m+2][n+2]
2.2、試探方向
在正常情況下,每個點有八個方向可以進行試探,設點座標為(x,y)即可對該點的座標進行加減1進行位置的變換,即加上move數組,定義如下:
typedef struct{ int x,y;}item;item move[8];//給move進行賦值void defineMove(item move[8]){ move[0].x = 0,move[0].y =1; move[1].x = 1,move[1].y =1; xmove[2].x = 1,xmove[2].y =0; move[3].x = 1,move[3].y =-1; move[4].x = 0,move[4].y =-1; move[5].x = -1,move[5].y =-1; move[6].x = 1,move[6].y =0; move[7].x = -1,move[7].y =1;}移動時進行運算:x = x+move[i].x; y = y+move[i].y;
2.3、棧的設計:
| |
| |
| |
| |
| 3,6,0(top) |
| 3,5,0 |
| 3,4,0 |
| 3,3,0 |
| 2,2,1 |
| 1,1,1 |
首先將起點壓入棧,並且從正右方的點進行尋路,如果為0,即進行壓棧,若不通即進行點的回溯,尋找其它方向。
棧的定義:
//點的定義typedef struct{int x,y,d;}point;
//棧定義typedef struct{ point data[MAXSIZE]; int top;}MazeStack;
2.4、防止重複到達某一點,以免發生死迴圈,將走過的點初始化為-1,即maze[x][y] = -1。
2.5、迷宮演算法的求解思想:
(1)、將棧進行初始化
(2)、將進入點座標及到達該點的方向(設為-1)入棧
(3)、while(棧不為空白)
{棧頂元素=>(x,y,d)
出棧
求出下一個要試探的方向d++
while(還有剩餘試探方向時)
{ if(d方向可走)
則{
(x,y,d)入棧
求出新點的座標(i,j)
將新點(i,j)切換為當前點(x,y)
if(x,y)==(m,n)結束
else 重設d++;
}
}
3、全部代碼:
/* *運用順序棧解決迷宮問題*/#include<stdio.h>#include<malloc.h>#define MAXSIZE 100#define m 6#define n 8//對棧中的元素進行定義,d為方向typedef struct{ int x,y,d;}point;//對棧的結構進行定義typedef struct{ point data[MAXSIZE]; int top;}MazeStack;//對移動數組進行定義,方便進行點的移動typedef struct{ int x,y;}item;//將棧設定為空白棧void setNULL(MazeStack *s){ s->top = -1;}//判斷棧是否為空白bool isEmpty(MazeStack *s){ if(s->top>=0) return false; else return true;}//進棧操作MazeStack * push(MazeStack *s,point x){ if(s->top>MAXSIZE-1){ printf("棧上溢出。\n"); return s; }else{ s->top++; s->data[s->top] = x; return s; }}//退棧操作point * pop(MazeStack *s){ if(isEmpty(s)){ printf("棧為空白。\n"); return NULL; }else{ s->top--; return &(s->data[s->top+1]); }}//取棧頂元素point * getTop(MazeStack *s){ if(isEmpty(s)){ printf("棧為空白。\n"); return NULL; }else{ return &(s->data[s->top]); }}//對移動的位置進行定義void defineMove(item xmove[8]){ xmove[0].x = 0,xmove[0].y =1; xmove[1].x = 1,xmove[1].y =1; xmove[2].x = 1,xmove[2].y =0; xmove[3].x = 1,xmove[3].y =-1; xmove[4].x = 0,xmove[4].y =-1; xmove[5].x = -1,xmove[5].y =-1; xmove[6].x = 1,xmove[6].y =0; xmove[7].x = -1,xmove[7].y =1;}//進行所有操作的測試int main(){ //對迷宮進行定義 int maze[m+2][n+2],x,y,i,j,d; //對移動的位置進行定義 item xmove[8]; //定義棧的起始點 point start,*p; //對棧進行定義 MazeStack *s; s = (MazeStack*)malloc(sizeof(MazeStack)); setNULL(s); //對移動的位置進行定義 defineMove(xmove); //對迷宮進行輸入 printf("請輸入迷宮:\n"); for(i = 0;i<m+2;i++) for(j = 0;j<n+2;j++) scanf("%d",&maze[i][j]); start.x = 1; start.y = 1; start.d = -1; p = (point*)malloc(sizeof(point)); //將起點壓入棧 s = push(s,start); while(!isEmpty(s)){ p = pop(s); x = p->x; y = p->y; d = p->d+1; while(d<8){ i = xmove[d].x+x; j = xmove[d].y+y; if(maze[i][j]==0){ p->d = d; s = push(s,*p); x = i; y = j; maze[x][y] = -1; point nw; nw.x = x; nw.y = y; nw.d = -1; s = push(s,nw); if(x==m&&y==n){ printf("找到出口。\n"); while(!isEmpty(s)){ p = pop(s); printf("%d %d %d\n",p->x,p->y,p->d); } return 1; }else{ break; } }else{ d++; } } } return 0;}