7.7 迷宫求解

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

7.7 迷宫求解的相关文章

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

AI-随机迷宫&amp;迷宫求解

本文记录了,人工智能中简单的搜索策略中的路径搜索策略中的A*算法,来实现迷宫寻路的问题.(这只是一次本人的课外作业) 完整的程序源码已经发送到我的Git.这里只记录了我的思路和感想以及收获. 产生随机迷宫 迷宫求解没有迷宫怎么可以呢.而本人是个懒人,每次都要手动输入迷宫,重复性的工作让我很不爽.你可以在程序中用数组定义一个迷宫啊,有强迫症的我,怎么可以这样随便的要求自己的程序呢.及时求解算法的出来了,但是测试数据有限,还是让我很不爽的,所以,干脆先花一些时间,写个随机迷宫的产生吧. 遇事先搜索,

栈实现迷宫求解(c++版)

相信大家都应该听过栈吧,一直想利用栈来实现一个算法,最近有点空,就利用栈的先进后出的特性来完成迷宫求的问题,下面将详细介绍栈的实现和迷宫求解的过程,可以很好的学习栈的使用. 栈有两种实现方法,一种是顺序,即数组形式,一种是线性,即链表形式,个人还是比较喜欢链表形式实现栈的基本功能. 首先弄一个简单的迷宫,如图: 我们很容易看出这个迷宫解的路径,那怎么让计算机帮我们求解出来呢. 首先我们要对迷宫数据化,很容易想到二维数组来表示,0表示通路,1表示障碍,即表示为: int map[4][4]={ {

迷宫求解

1.找出一条迷宫通路 //迷宫求解. #include"stdlib.h" #include"stdio.h" #include<stack> #include<iostream> using namespace std; typedef struct Pseat{ int x; int y; bool operator==(Pseat& rhs) { return x==rhs.x&&y==rhs.y; } //操作

转载:迷宫求解

迷宫求解----递归实现 2010-01-14 14:02:28|  分类: 算法及分析|举报|字号 订阅 一.问题的分析: 本问题的求解,关键是如何找到求解任意两个点间,按照以上基本思想而走出的路线.按照这个路线,我们可以通过图形函数来动态的显示迷宫的搜索过程. 计算机解迷宫解通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进,否则沿着原路退回,换一个方向继续探索,直至出后位置,求得一条通路.假如所有可能的通路都探索到位能到达出口,则所设定的迷宫没有通路.

利用栈实现迷宫求解

利用栈实现迷宫求解 前言:众所周知,栈是(First in last out)先进后出的数据结构,利用这个属性可以实现类似与回溯的方式,比如当前数据满足条件,则入栈,否则出栈返回上一级,依次循环. 在本题中,将每个迷宫路径上的点封装成上下左右四个方向数节点,先入栈迷宫入口节点,如果上下左右没被使用,则将其上下左右的点入栈,否则出栈.如果最终达到迷宫终点则成功,否则失败. 如下是每个节点的数据结构 1 typedef struct{ 2 int top; 3 int bottom; 4 int l

迷宫求解系统

编程语言:c++ 代码如下: main.cpp 1 #include <iostream> 2 #include <stack> 3 #include <stdio.h> 4 #include <windows.h> 5 #include "show.cpp" 6 #define N 100 7 #include "jiegou.cpp" 8 #include "shuru.cpp" 9 #incl

看数据结构写代码(13)栈的应用(四) 迷宫求解

这是一个 用 穷举法 解 迷宫问题 的一个示例,但在 效率 和 解的 最短路径上 就稍显不足了. 这 两个问题,留在 以后 空闲 时刻 解答. 欢迎指出代码不足 下面上代码: // Maze.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h> struct Postion { int x; int y; }; typedef int Direction; struct ElementType { P

应用栈求解迷宫问题(C++实现)

栈是数据结构中一种重要的线性结构,限定仅在表尾进行插入和删除操作的线性表,因此我们也可以认为它是一种特殊的线性表.由于栈的这个特点,我们又可以称其为后进先出的结构.如图所示: 由于栈具有后进先出的性质我们可以利用,是程序设计中一个有用的工具.利用栈我们可以来实现数制转换.后缀表达式求值.迷宫求解等等.在书本上我们可以看到用C语言实现的简单思路,但是程序仍旧存在许多bug.今天,我想尝试用强大的C++来实现. 迷宫问题的求解思路大致则是从入口出发,顺着某一方向向前探索,若能走通,则继续向前探索:若