棧實現迷宮
1.解決存儲問題
實現迷宮的存儲。用一個二維矩陣存儲
如下列迷宮:
0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,
1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,
0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,
1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,
1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,
0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,
0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,
0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,
1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,
0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,
0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,
2.解決移動問題
考慮移動:
有8個方向:
方位 方向代碼(dir) 行移動 (move[dir].vert) 列移動(move[dir].horiz)
N 0 -1 0
NE 1 -1 1
E 2 0 1
SE 3 1 1
S 4 1 0
SW 5 1 -1
W 6 0 -1
NW 7 -1 -1
數據結構表示:
typedef struct{
short int vert;
short int horiz;
} offsets;
offsets move[8];
若當前位置是maze[row][col]
那麽下一個位置是maze[next_row][next_col];
next_row=row+move[dir].vert;
next_col=col+move[dir].horiz;
3.解決邊界問題
並不是每個移動都有8個位置如邊和角的位置,所以為啦避免邊界檢查,所以再加上一圈邊界
若是m*n個元素 則需要(m+2)*(n+2)個存儲空間
如下圖:
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1,
1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1,
1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1,
1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,
1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1,
1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,
1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,
1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,
1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1,
1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
4.這裏所用的棧即是上一篇寫的基礎棧。
代碼如下:
1 #include<stdio.h> 2 #define MAX_STACK_SIZE 100 //棧的最大元素數 3 4 5 int EXIT_ROW=11,EXIT_COL=15,TRUE=1,FALSE=0,top; 6 //出口的行列,top棧頂 7 short int maze[13][17]={ //[m+2][p+2] ; //15*11迷宮 1,1開始,15,11結束 8 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9 1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1, 10 1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1, 11 1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1, 12 1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1, 13 1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1, 14 1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1, 15 1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1, 16 1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1, 17 1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1, 18 1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1, 19 1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1, 20 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 21 }; 22 short int mark[13][17]={ //[m+2][p+2] ; //走過的路程記錄 23 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 24 1,0,1,0,0,0,1,1,0,0,0,1,1,1,1,1,1, 25 1,1,0,0,0,1,1,0,1,1,1,0,0,1,1,1,1, 26 1,0,1,1,0,0,0,0,1,1,1,1,0,0,1,1,1, 27 1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1, 28 1,1,1,0,1,0,0,1,0,1,1,1,1,1,1,1,1, 29 1,0,0,1,1,0,1,1,1,0,1,0,0,1,0,1,1, 30 1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1, 31 1,0,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1, 32 1,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1, 33 1,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,1, 34 1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1, 35 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 36 }; 37 38 typedef struct{ 39 short int vert; 40 short int horiz; 41 } offsets; 42 offsets move[8]={// dir vert horiz 可以移動的位置8個方向 43 -1,0, // 0 上 44 -1,1, // 1 右上 45 0,1, // 2 右 46 1,1, // 3 右下 47 1,0, // 4 下 48 1,-1, // 5 左下 49 0,-1, // 6 左 50 -1,-1 // 7 左上 51 }; 52 53 typedef struct{ //定義棧的基礎元素 54 short int row; 55 short int col; 56 short int dir; 57 }element; 58 element stack[MAX_STACK_SIZE]; 59 60 bool IsFull(int *top ); 61 void Add(int *top,element item); 62 bool IsEmpty(int *top ); 63 element Delete(int *top); 64 65 66 void path(void) 67 { 68 int i,row,col,next_row,next_col,dir,found=FALSE; 69 element position; 70 71 mark[1][1]=1; //初始位置 記錄已經走過 72 top=0; //棧頂為0 73 stack[0].row=1; //給棧頂賦值 74 stack[0].col=1; 75 stack[0].dir=1; 76 77 while( top > -1 && !found) { 78 //當棧裏元素不空且沒有找到路徑時做循環 79 position = Delete(&top); //找不到出口時回到上一個位置 80 row = position.row; 81 col = position.col; 82 dir = position.dir; 83 84 while( dir < 8 && !found ){ //每一個方向 85 //主要用於找到出口 86 next_row=row+move[dir].vert; //每一個方向的下一步 87 next_col=col+move[dir].horiz; 88 if(next_row ==EXIT_ROW &&next_col ==EXIT_COL) //若發現到出口結束 89 { 90 found=TRUE; 91 } 92 else if(!maze[next_row][next_col] && !mark[next_row][next_col]){ 93 //若原矩陣和記錄矩陣都是 0(即未走過且不是墻壁) 94 mark[next_row][next_col]=1; //記錄這個地方已經走過 (封鎖避免重復走) 95 96 position.row=row; //當前位置換方向 97 position.col=col; 98 position.dir=++dir; 99 Add(&top,position); //入棧 添加回溯點 100 row=next_row; //下一個位置 重新從上部開始比較 101 col=next_col; 102 dir=0; 103 } 104 else ++dir; 105 } 106 } 107 108 if(found){ 109 printf("the path is:\n"); 110 printf("row col\n"); 111 112 for(i=0;i<=top;i++){ 113 printf("%2d%5d\n",stack[i].row,stack[i].col); 114 } 115 printf("%2d%5d\n",row,col); //下一個元素 116 printf("%2d%5d\n",EXIT_ROW,EXIT_COL); //出口 117 } 118 else 119 printf("the maze does not have a path\n"); 120 121 } 122 int main() 123 { 124 path(); 125 int i,j; 126 /* for(i=0;i<13;i++) 用於查看記錄矩陣 127 { 128 for(j=0;j<17;j++) 129 printf("%d",mark[i][j]); 130 printf("\n"); 131 }*/ 132 133 return 0; 134 } 135 136 137 bool IsFull(int * top )//1為滿0為不滿 138 { 139 if(*top >=MAX_STACK_SIZE-1){ 140 return 1; 141 } 142 else{ 143 return 0; 144 } 145 } 146 147 bool IsEmpty(int *top)//1為空 0為不空 148 { 149 if(*top == -1){ 150 return 1; 151 } 152 else{ 153 return 0; 154 } 155 } 156 void Add(int *top,element item) 157 { 158 if(*top >=MAX_STACK_SIZE-1){ 159 printf("棧滿"); 160 return ; 161 } 162 else 163 stack[++(*top)]=item; 164 } 165 element Delete(int *top) 166 { 167 if(*top == -1){ 168 printf("棧空"); 169 } 170 return stack[(*top)--]; 171 }
結果:
the path is: row col 1 1 2 2 1 3 1 4 1 5 2 4 3 5 3 4 4 3 5 3 6 2 7 1 8 2 9 3 9 4 8 5 7 6 7 7 8 8 9 8 10 9 10 10 9 11 9 12 9 13 8 14 9 15 10 15 11 15 走過路徑為9數字的; 11111111111111111 19199911999111111 11909119111991111 10119999111199111 11191111101191101 11191001011111111 19911011101001011 19111199111111111 10911911911111911 11199011911999091 10011111099111191 10100111110111101 11111111111111111 真實路徑; 11111111111111111 19199911111111111 11909111111111111 10119911111111111 11191111101111101 11191001011111111 11911011101001011 19111199111111111 10911911911111911 11199011911999091 10011111099111111 10100111110111101 11111111111111111 由於最後2步沒有入棧所以需要自己輸出一下
棧實現迷宮