迷宫求解,使用栈

       迷宫求解是数据结构中一个经典的程序设计题,一般情况下采用的式穷举求解的方法,即从迷宫的入口出发,沿着某一方向前进,若能走通则继续前进,若不通需原路退回后改变方向继续前进,直到找到出口为止,为了保证在任何位置都可以原路退回,自然使用“栈”就是很自然的了。


寻找迷宫路径的算法如下:
 

do{
 
若当前位置可通,
则{
将当前位置压入栈顶; /*纳入路径*/
若当前位置是出口位置,则结束;/*求得的路径已在栈中*/
否则切换当前位置的东临块为新的当前位置;
}
否则
{
若栈不空,且栈顶位置尚有其它方向未搜索,
则设定新的当前位置为沿顺时针方向旋转找到的栈顶位置的下一临块;
若栈不空但栈顶位置四周均不可通,

{
删去栈顶位置;
若栈不空,则重新测试新的栈顶位置,直到找到一个可通的相邻块或出栈至栈空;
}
}
}while(站不空);

以上图所示的迷宫为例,我们使用栈来寻找迷宫路径:
 

1
2  /********************main.c***********************/
3 #include <stdio.h>
4
5 #include <stdlib.h>
6
7 #include <string.h>
8
9 #include "MazePath.c"
10
11  int main()
12
13 {
14
15  int m[11][11] = {
16
17 {1,1,1,1,1,1,1,1,1,1,1},
18
19 {1,0,1,1,0,0,0,1,0,0,1},
20
21 {1,0,0,0,1,0,1,0,0,1,1},
22
23 {1,0,1,1,1,0,1,1,0,0,1},
24
25 {1,0,0,0,0,0,0,0,1,0,1},
26
27 {1,1,1,0,1,0,1,0,0,0,1},
28
29 {1,0,0,0,1,0,1,0,1,0,1},
30
31 {1,1,0,1,1,1,0,0,0,0,1},
32
33 {1,0,0,0,0,0,0,1,1,0,1},
34
35 {1,1,0,1,1,0,1,0,0,0,1},
36
37 {1,1,1,1,1,1,1,1,1,1,1}
38
39 };
40
41 MazeType maze = {m,11,11};
42
43 PosType start = {1,1},end = {9,9};
44
45 if(MazePath(maze,start,end))
46
47 {
48
49 printf("\nSuccessfully Find Way Out!\n");
50
51 return 0;
52
53 }
54
55 else
56
57 {
58
59 printf("No Way Out!\n");
60
61 return 0;
62
63 }
64
65 }
66
67 /*******************************************/

 


1 /**************MazePath.c*************/
2
3 #define MAXSIZE 1024
4
5 #define footed -1
6
7 #define marked -2
8
9 #define East 1
10
11 #define South 2
12
13 #define West 3
14
15 #define North 4
16
17 #define True 1
18
19 #define False 0
20
21 typedef int STATUS;
22
23 typedef int DirType;
24
25 typedef int BOOL;
26
27 typedef struct
28
29 {
30
31 void *ptr;
32
33 int row;
34
35 int colum;
36 }MazeType;
37
38 typedef struct
39
40 {
41
42 int x;
43
44 int y;
45
46 }PosType;
47
48 typedef struct
49
50 {
51
52 PosType seat;
53
54 DirType di;
55
56 }StackElement;
57
58 typedef struct
59
60 {
61
62 StackElement *base;
63
64 StackElement *top;
65
66 int size;
67
68 }Stack;
69
70
71 int InitStack(Stack *stp)
72
73 {
74
75 stp->top = stp->base = (StackElement *)malloc(sizeof(StackElement)*(stp->size));
76
77 if(stp->top)return 0;
78
79 else printf("Stack Initialized Error!\n");
80
81 return 1;
82
83 }
84
85
86 int PushStack(Stack *stp,StackElement *sep)
87
88 {
89
90 if(stp->top-stp->base == stp->size-1)
91
92 {
93
94 printf("Stack is Full!\n");
95
96 return 1;
97
98 }
99
100 *(stp->top) = *sep;
101
102 stp->top++;
103
104 return 0;
105
106 }
107
108
109 int PopStack(Stack *stp,StackElement *sep)
110
111 {
112
113 if(stp->base == stp->top)
114
115 {
116
117 printf("Stack is Empty");
118
119 return 1;
120
121 }
122
123 stp->top--;
124
125 *sep = *(stp->top);
126
127 return 0;
128
129 }
130
131
132 int IsStackEmpty(Stack *stp)
133
134 {
135
136 if(stp->top == stp->base)return 1;
137
138 else return 0;
139
140 }
141
142
143 int GetTop(Stack *stp,StackElement *sep)
144
145 {
146
147 if(stp->top == stp->base)
148
149 {
150
151 printf("Stack is Empty!\n");
152
153 return 1;
154
155 }
156
157 else *sep = *(stp->top-1);
158
159 return 0;
160
161 }
162
163
164 void DispPos(PosType pos)
165
166 {
167
168 printf("Position: %d %d \n",pos.x,pos.y);
169
170 }
171
172
173 void DispPath(Stack *st)
174
175 {
176
177 StackElement *sep;
178
179 sep = st->base;
180
181 printf("The Path is as following:\n");
182
183 while(sep < st->top)
184
185 {
186
187 printf("(%d,%d)",(sep->seat).x,(sep->seat).y);
188
189 if(sep!=st->top-1)printf("-->");
190
191 sep++;
192
193 }
194
195 }
196
197
198 PosType NextPos(PosType pos,DirType dir)
199
200 {
201
202 switch(dir)
203
204 {
205
206 case East:
207
208 pos.y++;
209
210 return pos;
211
212 case South:
213
214 pos.x++;
215
216 return pos;
217
218 case West:
219
220 pos.y--;
221
222 return pos;
223
224 case North:
225
226 pos.x--;
227
228 return pos;
229
230 default:
231
232 return pos;
233
234 }
235
236 }
237
238
239 STATUS MazePath(MazeType maze,PosType start,PosType end)
240
241 {
242
243 int m[maze.row][maze.colum];
244
245 int i=0,j=0;
246
247 memcpy(m,maze.ptr,sizeof(int)*(maze.row)*(maze.colum));
248
249 /*for(i=0;i<maze.row;i++)
250
251 {
252
253 for(j=0;j<maze.colum;j++)
254
255 {
256
257 printf("%d ",m[i][j]);
258
259 }
260
261 printf("\n");
262
263 }*/ /*打印传入的迷宫*/
264
265 Stack st;
266
267 st.size = MAXSIZE;
268
269 InitStack(&st);
270
271 StackElement se;
272
273 PosType curpos = start;
274
275 DispPos(curpos);
276
277 do{
278
279 if(m[curpos.x][curpos.y] == 0)
280
281 {
282
283 m[curpos.x][curpos.y] = footed;
284
285 se.seat = curpos;
286
287 se.di = East;
288
289 PushStack(&st,&se);
290
291 if((curpos.x == end.x)&&(curpos.y == end.y))
292
293 {
294
295 printf("\nSuccessfully arrived at Exit!\n");
296
297 DispPath(&st);
298
299 return True;
300
301 }
302
303 curpos = NextPos(curpos,se.di);
304
305 DispPos(curpos);
306
307 }
308
309 else
310
311 {
312
313 if(!IsStackEmpty(&st))
314
315 {
316
317 PopStack(&st,&se);
318
319 }
320
321 while((se.di ==4)&&!IsStackEmpty(&st))
322
323 {
324
325 m[curpos.x][curpos.y] = marked;
326
327 PopStack(&st,&se);
328
329 }
330
331 if(se.di < 4)
332
333 {
334
335 se.di++;
336
337 PushStack(&st,&se);
338
339 curpos = NextPos(se.seat,se.di);
340
341 DispPos(curpos);
342
343 }
344
345 }
346
347 }while(!IsStackEmpty(&st));
348
349 return False;
350
351 }
352
353 /*******************************************/

 



编译后,运行输出以下结果:
Position: 1  1
Position: 1  2
Position: 2  1
Position: 2  2
Position: 2  3
Position: 2  4
Position: 3  3
Position: 2  2
Position: 1  3
Position: 3  2
Position: 2  1
Position: 1  2
Position: 3  1
Position: 3  2
Position: 4  1
Position: 4  2
Position: 4  3
Position: 4  4
Position: 4  5
Position: 4  6
Position: 4  7
Position: 4  8
Position: 5  7
Position: 5  8
Position: 5  9
Position: 5  10
Position: 6  9
Position: 6  10
Position: 7  9
Position: 7  10
Position: 8  9
Position: 8  10
Position: 9  9

Successfully arrived at Exit!
The Path is as following:
(1,1)-->(2,1)-->(3,1)-->(4,1)-->(4,2)-->(4,3)-->(4,4)-->(4,5)-->(4,6)-->(4,7)-->(5,7)-->(5,8)-->(5,9)-->(6,9)-->(7,9)-->(8,9)-->(9,9)
Successfully Find Way Out!

可以看到寻找到的路径为:(1,1)-->(2,1)-->(3,1)--> (4,1)-->(4,2)-->(4,3)-->(4,4)-->(4,5)-->(4,6)-->(4,7)-->(5,7)-->(5,8)-->(5,9)-->(6,9)-->(7,9)-->(8,9)-->(9,9)

 

posted @ 2010-10-30 20:20  leao  阅读(1371)  评论(1编辑  收藏  举报