本文是对严蔚敏老师的数据结构一书中,第3.2.4一节 迷宫求解问题的实现

迷宫图如下所示

本代码用到的栈为上一篇文章中的链表栈

ElemType.h

 1 #ifndef _ELEMTYPE_H_
 2 #define _ELEMTYPE_H_
 3 
 4 /*定义需要的数据类型,这里可以是基本数据类型,也可以是结构体数据类型,
 5   结构体中最好不要使用指针,使用结构体时请包含相关头文件*/
 6 
 7 typedef struct{
 8     int x;                //横向坐标
 9     int y;                //纵向坐标
10 }PosType;
11 
12 typedef struct{
13     int ord;            //通道在路径上的序号    
14     PosType seat;        //通道在迷宫中的坐标位置
15     int di;                //从此通道块走向下一通道块的方向
16                         //1 表示上 2表示下 3表示左 4表示右
17 }MazePath;
18   
19 typedef MazePath ElemType;
20 typedef ElemType* PElemType;
21 typedef const ElemType* PCElemType;
22 
23 
24 /****************************************
25  Purpose :     打印数据
26  Input   :     pVal --要被打印的数据
27  Return  :     None
28 *****************************************/
29  void visit(PCElemType pVal);
30 
31 #endif

ElemType.c

#include <stdio.h>
#include "ElemType.h"
/*************************************************************************
 Function:     visit()
 Purpose :     打印输出数据
 Input   :     pVal --要被打印的数据
 Return  :     None
 Modify  :
 Remark  :
 *************************************************************************/
 void visit(PCElemType pVal)
 {
    extern char g_nMapVisit[10][10];
    switch(pVal->di)
    {
        case 1:
            g_nMapVisit[pVal->seat.x][pVal->seat.y] ='S';        
            //'↑';
            break;
        case 2:
            g_nMapVisit[pVal->seat.x][pVal->seat.y] ='X';    
            //printf(" ↓ ");
            break;
        case 3:
            g_nMapVisit[pVal->seat.x][pVal->seat.y] ='Z';
            //printf(" ← ");
            break;
        case 4:
            g_nMapVisit[pVal->seat.x][pVal->seat.y] ='Y';
            //printf(" → ");
            break;
    }
 }

MazePath.c

  1 /*********************************************************************
  2 *:
  3 *:          Filename: MazePaht.c
  4 *:
  5 *:          Author: DongXiaolin
  6 *:          Copyright (c) 2012, DongXiaolin
  7 *:
  8 *:        Created at: 2012.06.15
  9 *:     Last modified: 2012.06.15  
 10 *:             
 11 *:      Introduction: 迷宫求解问题(栈实现)
 12 *:                    
 13 *:
 14 *:*********************************************************************/
 15 #include <stdio.h>
 16 #include "LinkListStack.h"
 17 
 18 
 19 #define N 10
 20 
 21 /*地图信息, 1表示 不能通过 0表示能通过 2表示已经走过 3表示试探过*/
 22 int g_nMap[][N]=
 23     {
 24         {1,1,1,1,1,1,1,1,1,1},
 25         {1,0,0,1,0,0,0,1,0,1},
 26         {1,0,0,1,0,0,0,1,0,1},
 27         {1,0,0,0,0,1,1,0,0,1},
 28         {1,0,1,1,1,0,0,0,0,1},
 29         {1,0,0,0,1,0,0,0,0,1},
 30         {1,0,1,0,0,0,1,0,0,1},
 31         {1,0,1,1,1,0,1,1,0,1},
 32         {1,1,0,0,0,0,0,0,0,1},
 33         {1,1,1,1,1,1,1,1,1,1},
 34     };
 35 int g_nStartX = 1;
 36 int g_nStartY = 1;
 37 int g_nEndX = 8;
 38 int g_nEndY = 8;
 39 
 40 char g_nMapVisit[N][N]={'0'};
 41 
 42 void Display(LinkListStack *pStack, int flag)
 43 {
 44     //system("clear");
 45     int i,j;
 46     for(i=0;i<N;i++)
 47     {
 48         for(j=0;j<N;j++)
 49         {
 50             if(i == g_nStartX && j == g_nStartY)
 51             {
 52                 //画起点
 53                 g_nMapVisit[i][j]= 'B';
 54             }
 55             else if(i == g_nEndX && j == g_nEndY)
 56             {
 57                 //画终点
 58                 g_nMapVisit[i][j] = 'E';
 59             }
 60             
 61             else if(g_nMap[i][j] == 1)
 62             {
 63                 g_nMapVisit[i][j] ='#';
 64             }
 65             else
 66             {
 67                 g_nMapVisit[i][j] ='O';
 68             }
 69         }
 70     }
 71     TraverseLinkListStack(pStack, visit);
 72     
 73     
 74     for(i=0;i<N;i++)
 75     {
 76         for(j=0;j<N;j++)
 77         {
 78             switch(g_nMapVisit[i][j])
 79             {
 80                 case 'S':    printf("");
 81                     break;
 82                 case 'X':    printf("");
 83                     break;
 84                 case 'Z':    printf("");
 85                     break;
 86                 case 'Y':    printf("");
 87                     break;
 88                 default:
 89                     printf(" %c ", g_nMapVisit[i][j]);
 90             }
 91             
 92         }
 93         printf("\n");
 94     }
 95     
 96     getchar();
 97 }
 98 
 99 
100 
101 /*************************************************************************
102  Purpose :     判断当前位置是否可通过
103  Input   :     pos            --坐标指针
104  Return  :     0            --可以通过
105             其他        --不可通过
106  Modify  :
107  *************************************************************************/
108 int Pass(PosType* pos)
109 {
110     if(pos == NULL)
111     {
112         return -1;
113     }
114     if(g_nMap[pos->x][pos->y] == 0)
115     {
116         return 0;
117     }
118     return -1;
119 }
120 
121 void FootPrint(PosType* pos)
122 {
123     //表示该坐标已经走过
124     g_nMap[pos->x][pos->y] = 2;
125 }
126 
127 void MarkPrint(PosType* pos)
128 {
129     //表示该坐标已试探过,且不可通过
130     g_nMap[pos->x][pos->y] = 3;
131 }
132 
133 /*************************************************************************
134  Purpose :     判断是否结束
135  Input   :     pos            --坐标指针
136  Return  :     0            --结束
137             其他        --未结束
138  Modify  :
139  *************************************************************************/
140 int IsEnd(PosType* pos)
141 {
142     if(pos->x == g_nEndX && pos->y == g_nEndY)
143     {
144         return 0;
145     }
146     return -1;
147 }
148 
149 /*************************************************************************
150  Purpose :     定位下一个点
151  Input   :     mData        --结构指针
152  Return  :     None
153  Modify  :
154  *************************************************************************/
155 void FindNextPos(ElemType* pData)
156 {
157     switch(pData->di)
158     {
159         case 1:            //该点的上方
160             pData->seat.x = pData->seat.x - 1;
161             if(pData->seat.x < 0)
162             {
163                 pData->seat.x = 0;
164             }
165             break;
166         case 2:            //该点的下方
167             pData->seat.x = pData->seat.x + 1;
168             if(pData->seat.x > N-1)
169             {
170                 pData->seat.x = N-1;
171             }
172             break;
173         case 3:            //该点的左方
174             pData->seat.y = pData->seat.y - 1;
175             if(pData->seat.y < 0)
176             {
177                 pData->seat.y = 0;
178             }
179             break;
180         case 4:            //该点的右方
181             pData->seat.y = pData->seat.y + 1;
182             if(pData->seat.y > N-1)
183             {
184                 pData->seat.y = N-1;
185             }
186             break;
187     }
188     
189     //对方向进行初始化
190     pData->di = 1;
191     pData->ord++;
192 }
193 
194 //迷宫求解
195 int MazePathCalc()
196 {
197     LinkListStack mStack;
198     ElemType mData;
199     InitLinkListStack(&mStack);
200     mData.ord = 1;
201     mData.seat.x = g_nStartX;
202     mData.seat.y = g_nStartY;
203     mData.di = 1;
204     do
205     {
206         if(Pass(&(mData.seat)) == 0)                //当前位置可以通过,即是未曾走过的通道
207         {
208             FootPrint(&(mData.seat));                //留下足迹
209             PushLinkListStack(&mStack, &mData);        //入栈
210             printf("入栈1 [%d:%d][%d]\n",mData.seat.x,mData.seat.y,mData.di);
211             //getchar();
212             Display(&mStack,1);
213             if(IsEnd(&(mData.seat)) == 0)                //是否是终点
214             {
215                 DestroyLinkListStack(&mStack);
216                 return 0;
217             }
218             FindNextPos(&mData);                    //查找下一个点
219         }
220         else                                        //当前位置不能通过
221         {
222             if(IsEmptyLinkListStack(&mStack) != 0)        
223             {
224                 PopLinkListStack(&mStack, &mData);
225                 printf("出栈1 [%d:%d][%d]\n",mData.seat.x,mData.seat.y,mData.di);
226                 Display(&mStack,0);
227                 while(mData.di == 4&& IsEmptyLinkListStack(&mStack) != 0)
228                 {
229                     MarkPrint(&(mData.seat));
230                     PopLinkListStack(&mStack, &mData);
231                     printf("出栈2 [%d:%d][%d]\n",mData.seat.x,mData.seat.y,mData.di);
232                     Display(&mStack,0);
233                 }
234                 if(mData.di < 4)
235                 {
236                     mData.di++;
237                     PushLinkListStack(&mStack, &mData);        //换下一个方向
238                     printf("入栈2 [%d:%d][%d]\n",mData.seat.x,mData.seat.y,mData.di);
239                     Display(&mStack,1);
240                     FindNextPos(&mData);
241                 }
242             }
243         }
244     }while(IsEmptyLinkListStack(&mStack) != 0);
245     DestroyLinkListStack(&mStack);
246     return -1;
247 }
248 
249 int main(int argc, char* argv[])
250 {
251     if(MazePathCalc())
252     {
253         printf("失败,未找到出口\n");
254         return 1;
255     }
256     
257     printf("成功,已找到出口\n");
258     return 0;
259 }

上述程序,清晰的演示了迷宫求解的每一个步骤,效果如下

 

。。。。。

 

 

本程序按照上下左右的顺序来找路径,4个方向的先后顺序不同,则找到的路径亦不相同。

posted on 2013-08-07 12:55  dspeeding  阅读(757)  评论(1编辑  收藏  举报