7-8 Maze1.c
1 #include <stdio.h> 2 #define MAXLEN 30 // 迷宫包括外墙最大行列数目 3 #define INIT_SIZE 100 // 存储空间初始分配量 4 typedef struct 5 { 6 int row; //迷宫的行数 7 int column; //迷宫的列数 8 char grid[MAXLEN][MAXLEN]; //1表示障碍,0表示空,2表示可通,3表示已走过但不通 9 }MazeType; // 迷宫类型 10 typedef struct // 迷宫中的坐标 11 { 12 int row;//行号 13 int column; //列号 14 }Coordinate; 15 typedef struct 16 { 17 int ord; // 当前位置在路径上的序号 18 Coordinate seat; // 当前坐标 19 int di; // 往下一坐标的方向 20 }MazeNode; // 栈元素类型 21 typedef struct 22 { 23 MazeNode base[INIT_SIZE]; //迷宫节点信息 24 int top; //栈顶指针 25 }Stack; // 栈类型 26 int InitStack(Stack *S) // 构造空栈s 27 { 28 S->top = -1; 29 return 1; 30 } 31 int StackEmpty(Stack *s) // 若s为空返回TRUE,否则返回FALSE 32 { 33 if (s->top == -1) 34 return 1; 35 return 0; 36 } 37 int StackIsFull(Stack *s) //判断栈是否为满 38 { 39 if (s->top == INIT_SIZE - 1) 40 return 1; 41 else 42 return 0; 43 } 44 int Push(Stack *s, MazeNode mn) // 插入元素e为新的栈顶元素 45 { 46 if (!StackIsFull(s)) //若栈未满 47 { 48 s->top++; //修改栈顶指针 49 s->base[s->top] = mn; //将节点信息入栈 50 } 51 } 52 int Pop(Stack *s, MazeNode *mn) // 若栈不空删除栈//顶元素用e返回并返回OK,否则返回ERROR 53 { 54 if (s->top != -1) //栈不为空 55 { 56 *mn = s->base[s->top]; 57 s->top--; 58 return 1; 59 } 60 return 0; 61 } 62 int DestroyStack(Stack *s) //销毁栈S 63 { 64 s->top=-1; 65 return 1; 66 } 67 int MazeInit(MazeType *maze) // 初始化迷宫 68 { 69 int m, n, i, j; 70 printf("输入迷宫的行数和列数:"); 71 scanf("%d%d", &maze->row, &maze->column); // 迷宫行和列数 72 for (i = 0; i <= maze->column + 1; i++)// 迷宫行外墙 73 { 74 maze->grid[0][i] = ‘1‘; //设置为障碍墙 75 maze->grid[maze->row + 1][i] = ‘1‘; 76 } 77 for (i = 0; i <= maze->row + 1; i++)// 迷宫列外墙 78 { 79 maze->grid[i][0] = ‘1‘;//设置为障碍墙 80 maze->grid[i][maze->column + 1] = ‘1‘; 81 } 82 for (i = 1; i <= maze->row; i++) // 初始化迷宫 83 for (j = 1; j <= maze->column; j++) 84 maze->grid[i][j] = ‘0‘; //设置为可通过 85 printf("输入障碍墙的坐标(输入坐标(0,0)结束): "); // 86 while(1) 87 { 88 scanf("%d%d", &m, &n); // 接收障碍的坐标 89 if(m==0) //输入0 90 break; //结束坐标的输入 91 if (m<=0 || n<=0 || m > maze->row || n > maze->column) //越界 92 { 93 printf("坐标越界,重新输入!\n"); 94 continue; 95 } 96 maze->grid[m][n] = ‘1‘; // 迷宫障碍用‘1‘标记 97 } 98 return 1; 99 } 100 int Pass(MazeType *maze, Coordinate pos) //判断指定坐标是否可通过 101 { 102 if (maze->grid[pos.row][pos.column] == ‘0‘) // 可通 103 return 1; 104 else 105 return 0; 106 } 107 int MarkerPass(MazeType *maze, Coordinate pos) //标记可通过 108 { 109 maze->grid[pos.row][pos.column] = ‘2‘; //"2"表示可通 110 return 1; 111 } 112 Coordinate NextCoord(Coordinate pos, int i) //获取下一位置 113 { 114 switch(i) // 1.2.3.4分别表示东,南,西,北方向 115 { 116 case 1: 117 pos.column += 1; //向右侧查找 118 break; 119 case 2: //向下方查找 120 pos.row += 1; 121 break; 122 case 3: //向左侧查找 123 pos.column -= 1; 124 break; 125 case 4: //向上方查找 126 pos.row -= 1; 127 break; 128 default: 129 exit(0); 130 } 131 return pos; 132 } 133 int MarkerNoPass(MazeType *maze, Coordinate pos) // 曾走过但不是通路标记并返回OK 134 { 135 maze->grid[pos.row][pos.column] =‘3‘; // "3"表示曾走过但不通 136 return 1; 137 } 138 int MazePath(MazeType *maze, Coordinate start, Coordinate end)//从迷宫maze的入口到出口查找路径 139 { 140 Stack S; //定义栈 141 Coordinate pos; 142 int curstep; // 当前序号,1.2.3.4分别表示东,南,西,北方向 143 MazeNode e; 144 InitStack(&S); //初始化栈 145 pos = start; //从入口位置开始查找路径 146 curstep = 1; // 探索第一步 147 do 148 { 149 if (Pass(maze, pos)) //若指定位置可通过 150 { 151 MarkerPass(maze, pos); //标记能通过 152 e.ord = curstep; //保存步数 153 e.seat = pos; //保存当前坐标 154 e.di = 1; //向右侧控测 155 Push(&S, e); //将节点添加到栈中(保存路径) 156 if (pos.row == end.row && pos.column == end.column) //若当前位置是出口坐标 157 { 158 DestroyStack(&S); //释放栈占用的空间 159 return 1;//返回查找成功 160 } 161 else //与出口坐标不同 162 { 163 pos = NextCoord(pos, 1);//向右侧探测 164 curstep++; //增加前进步数 165 } 166 } 167 else //若指定位置不通(为障碍墙或已走过) 168 { 169 if (!StackEmpty(&S))//若栈不为空(之前有走过的位置) 170 { 171 Pop(&S, &e); //出栈(返回上一步的位置) 172 while (e.di == 4 && !StackEmpty(&S)) //上一步4个方向都探测完,且栈不为空 173 { 174 MarkerNoPass(maze, e.seat); //标记该位置不为通 175 Pop(&S, &e);//出栈(返回上一步) 176 } 177 if (e.di < 4) //若未探测完4个方向 178 { 179 e.di++; //准备探测下一个方向 180 Push(&S, e);//将当前节点入栈(保存当前位置,准备下一位置的探测) 181 pos = NextCoord(e.seat, e.di); //查找下一个应该探测位置的坐标 182 } 183 } 184 } 185 }while (!StackEmpty(&S)); 186 //程序运行到这里,表示没有能通达的路径 187 DestroyStack(&S); //释放栈占用的空间 188 return 0; //返回失败 189 } 190 void PrintMaze(MazeType *maze)//输出迷宫 191 { 192 int i, j; 193 printf("\n迷宫路径(◇表示通路):\n"); 194 for (i = 0; i <= maze->row + 1; i++) 195 { 196 for (j = 0; j <= maze->column + 1; j++) 197 { 198 if ( maze->grid[i][j] == ‘1‘) //若是障碍墙 199 printf("█"); 200 else if ( maze->grid[i][j] == ‘2‘) //若是可通路径 201 printf("◇"); 202 else //其他位置 203 printf(" "); 204 } 205 printf("\n"); 206 } 207 } 208 int main() 209 { 210 MazeType maze; //迷宫数据 211 Coordinate start, end; 212 char cmd; 213 printf("创建迷宫\n"); 214 if (!MazeInit(&maze))// 初始化并创建迷宫 215 { 216 printf("\n创建迷宫结构时出错!\n"); 217 exit(-1); // 初始化错误 218 } 219 do // 输入迷宫入口坐标 220 { 221 printf("\n输入迷宫入口坐标:"); 222 scanf("%d%d", &start.row, &start.column); 223 if (start.row > maze.row || start.column > maze.column) 224 { 225 printf("\n输入的坐标越界,重新输入!\n"); 226 continue; 227 } 228 }while (start.row > maze.row || start.column > maze.column); 229 do// 输入迷宫出口坐标 230 { 231 printf("\n输入迷宫出口坐标:"); 232 scanf("%d%d", &end.row, &end.column); 233 if (end.row > maze.row || end.column > maze.column) 234 { 235 printf("\n输入的坐标越界,重新输入!\n"); 236 continue; 237 } 238 }while (end.row > maze.row || end.column > maze.column); 239 if (!MazePath(&maze, start, end)) //调用函数查找路径 240 printf("\n没有路径可由入口到达出口!\n"); 241 else 242 PrintMaze(&maze); // 打印找到的路径 243 getch(); 244 return 0; 245 }
时间: 2024-10-24 12:01:59