题目来自于严蔚敏《数据结构》,参考伪代码实现的程序:
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(" "); 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(" "); 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(" "); 200 } 201 return 0; 202 }