应用栈解决迷宫问题的C语言实现

题目来自于严蔚敏《数据结构》,参考伪代码实现的程序:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 //记录通道块在迷宫矩阵当中的横、纵坐标 
  4 struct Position{
  5     int x;
  6     int y;
  7 }; 
  8 //放入栈当中的通道块元素 
  9 struct SElement {
 10     int ord;//记录此通道块在整个通道当中的次序 
 11     Position p;//记录此通道块在矩阵当中的位置 
 12     int di;//记录下一次测试这一路径的临近路径的位置 
 13 }; 
 14 //创建栈数据结构
 15 #define STACK_INIT_SIZE 100
 16 #define STACKINCREMENT 10
 17 struct MyStack{
 18     SElement* base;
 19     SElement* top;
 20     int stacksize;
 21 };
 22 //创建一个栈如果创建成功则返回1,否则就返回0
 23 int InitStack(MyStack* s)
 24 {
 25     s->base=(SElement*)malloc(STACK_INIT_SIZE*sizeof(SElement));//为栈分配初始空间 
 26     if(!s->base) return 0;
 27     s->top=s->base;//设定为空栈 
 28     s->stacksize=STACK_INIT_SIZE;
 29     return 1; 
 30 }
 31 //判断栈是否为空,如果是空的就返回0,否则就返回1 
 32 int IsStackEmpty(MyStack* s)
 33 {
 34     if(s->top==s->base) return true;
 35     return false;
 36 } 
 37 //获取栈顶元素,如果栈为空就返回0 否则就返回1
 38 int GetTop(MyStack* s,SElement* e)
 39 {
 40     if(IsStackEmpty(s)) return 0;
 41     e=s->top-1;
 42     return 1; 
 43 }
 44 //获取栈的长度,并且通过程序返回 
 45 int StackLength(MyStack* s)
 46 {
 47     return s->top-s->base;
 48 }
 49 //插入元素e为新的栈顶元素,插入成功则返回1,否则返回0
 50 int  Push(MyStack* s,SElement e)
 51 {
 52     if(s->top-s->base>=STACK_INIT_SIZE)
 53     {
 54         s->base=(SElement*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElement));
 55         if(!s->base) return 0;
 56         s->top=s->base+s->stacksize;
 57         s->stacksize+=STACKINCREMENT;
 58     }
 59     *(s->top)=e;
 60     s->top++;
 61     return 1;
 62 }
 63 //弹出栈顶元素赋值给e弹出成功返回1,弹出失败返回0
 64 int Pop(MyStack* s,SElement* e)
 65 {
 66     if(IsStackEmpty(s)) return 0;
 67     *e=*(s->top-1);
 68     s->top--;
 69     return 1;
 70 } 
 71 //定义墙元素为2 可走路径为0 已知路径为curStep 不能够通过的路径为-1 
 72 #define MazeScale 10
 73 int Maze[MazeScale][MazeScale]={{2,2,2,2,2,2,2,2,2,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,0,0,2,2,0,0,2},
 74 {2,0,2,2,2,0,0,0,0,2},{2,0,0,0,2,0,0,0,0,2},{2,0,2,0,0,0,2,0,0,2},{2,0,2,2,2,0,2,2,0,2},{2,2,0,0,0,0,0,0,0,2},{2,2,2,2,2,2,2,2,2,2}};
 75 //辅助函数考察当前路径能否通过 
 76 bool Pass(Position posi)
 77 {
 78     //只有路径所在位置的数字为0的是可以走的 
 79     if(Maze[posi.x][posi.y]==0)
 80     {
 81         return true;
 82     } 
 83     return false; 
 84 }
 85 //按顺时针方向从东开始寻找矩阵当中某一个位置的临近位置 
 86 Position NextPosition(Position now,int direction)
 87 {
 88     Position next;
 89     int x=now.x;
 90     int y=now.y;
 91     switch(direction)
 92     {
 93         //
 94         case 1:{
 95             next.x=x;
 96             next.y=y+1;
 97             break;
 98         }
 99         //
100         case 2:{
101             next.x=x+1;
102             next.y=y; 
103             break;
104         }
105         //西
106         case 3:{
107             next.x=x;
108             next.y=y-1;
109             break;
110         }
111         //
112         case 4:
113         {
114             next.x=x-1;
115             next.y=y;
116             break;
117         } 
118         default:break;
119     }
120     return next;
121 }
122 //留下足迹 
123 void FootPrint(Position p,int step)
124 {
125     Maze[p.x][p.y]=step;
126 }
127 //路径不可走的话就留下-1的标记 
128 void MarkPrint(Position p)
129 {
130     Maze[p.x][p.y]=-1;
131 }
132 int main()
133 {
134     //打印出迷宫矩阵 
135     for(int i=0;i<MazeScale;i++)
136     {
137         for(int j=0;j<MazeScale;j++)
138         {
139             printf("%d ",Maze[i][j]);
140         }
141         printf("\n");
142     }
143     //迷宫程序主体
144     MyStack  path;//记录路径的栈
145     InitStack(&path);//初始化路径数组
146     Position curp;//当前被试位置
147     //初始化当前位置为矩阵入口 
148     curp.x=1;
149     curp.y=1;
150     int curStep=1;//被探索的步数 
151     do
152     {
153         if(Pass(curp))
154         {
155             FootPrint(curp,curStep);//可走就在迷宫里面留下足迹 
156             //创建一个栈元素,存储可行路径的相关值,将这个元素存储到栈当中
157             SElement e;
158             e.di=1;//意味着下一个被试路块为这一个路块的正上方的路块 
159             e.ord=curStep;
160             e.p.x=curp.x;
161             e.p.y=curp.y;
162             Push(&path,e);//将路径块入栈 
163             if(curp.x==MazeScale-2 && curp.y==MazeScale-2) break; //如果被压入的路径块到了迷宫的终点就退出循环
164             //找到下一个被试块
165             curp=NextPosition(curp,1);//找到前一个被试块东面的路径块作为被试块
166             curStep++;//被探索的步数加一 
167         }else//如果当前被试路径不能够通过的话 
168         { 
169             if(!IsStackEmpty(&path))
170             {
171                 SElement e;
172                 Pop(&path,&e);
173                 curStep--;
174                 //将这一段所有的周围路径都已经被测试过的路径从栈中清除 
175                 while(e.di==4 && !IsStackEmpty(&path)){
176                     MarkPrint(e.p); 
177                     Pop(&path,&e);
178                     curStep--;
179                 }
180                 //如果当前栈顶还有未被测试的路径就测试剩余的周围路径 
181                 if(e.di<4)
182                 {
183                     curp=NextPosition(e.p,e.di+1);
184                     e.di++;
185                     curStep++;
186                     Push(&path,e);
187                 }
188             }
189         } 
190     }while(!IsStackEmpty(&path));
191     printf("\n");
192     //打印出结果迷宫矩阵 
193     for(int i=0;i<MazeScale;i++)
194     {
195         for(int j=0;j<MazeScale;j++)
196         {
197             printf("%d   ",Maze[i][j]);
198         }
199         printf("\n");
200     }
201     return 0;
202 }

 

posted @ 2016-10-13 20:40  NewRookie  阅读(15715)  评论(2编辑  收藏  举报