應用棧解決迷宮問題的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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM