運用棧求解迷宮問題C/C++

用棧解決基本的迷宮問題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 8
int 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;
}


   
                               





 


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