码迷,mamicode.com
首页 > 其他好文 > 详细

7.7 迷宫求解

时间:2016-07-19 20:50:33      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

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 }

 

7.7 迷宫求解

标签:

原文地址:http://www.cnblogs.com/wozixiaoyao/p/5686022.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!