数据结构实验-迷宫问题汇总
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告
实验课名称:数据结构实验 实验名称:迷宫问题
班级:20130613
学号:16 姓名:施洋 时间:2015-5-18
一、问题描述
这是心理学中的一个经典问题。心理学家把一只老鼠从一个无顶盖的大盒 子的入口处放
入,让老鼠自行找到出口出来。迷宫中设置很多障碍阻止老鼠前行, 迷宫唯一的出口处放有一块奶酪,吸引老鼠找到出口。
简而言之,迷宫问题是解决从布置了许多障碍的通道中寻找出路的问题。 本
题设置的迷宫如图1所示。
为可通处。设每个点有四个可通方向,分别为东、 右下角为出
口。迷宫有一个入口,一个出口。设计
二、数据结构设计
以一个m K n 的数组mg 表示迷宫,每个元素表示一个方块状态,数组元素 0和1
分别表示迷宫中的通路和障碍。迷宫四周为墙,对应的迷宫数组的边界元素均为 1。根据题目中
的数据,设置一个数组 mg 如下
int mg[M+2][N+2]= {
{1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1}, {1,1,0,0,0,1,1,1}, {1,0,0,1,0,0,0,1}, {1,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1}
};在算法中用到的栈采用顺序存储结构,将栈定义为 Struct {int i; //
图1迷宫示意图 迷宫四周设为墙;无填充处, 南、西、北。左上角为入口。 程序求解迷宫的一条通路。 当前方块的行号
入口
/出口
当前方块的列号
是下一个相邻的可走的方位号 定义栈
// 初始化栈
、算法设计
要寻找一条通过迷宫的路径,就必须进行试探性搜索,只要有路可走就前进 步,无路可进,换一个方向进行尝试;当所有方向均不可走时,则沿原路退回 步(称为回溯),重新选择未走过可走的路,如此继续,直至到达出口或返回 入口(没有通路)。在探索前进路径时,需要将搜索的踪迹记录下来,以便走不 通时,可沿原路返回到前一个点换一个方向再进行新的探索。后
退的尝试路径与 前进路径正好相反,因此可以借用一个栈来记录前进路径。
方向:每一个可通点有4个可尝试的方向,向不同的方向前进时,目的地的 坐标不同。预先把4个方向上的位移存在一个数组中。如把上、右、下、左(即 顺时针方向)依次编号为0、
1、2、3.其增量数组move[4]如图3所示。
图2数组move[4]
Ci-1 J)方位0
方位1
(i, j)
3个属性:一个横坐标属性i 、一个列坐标属性 j 和一个方向
属性di ,表示其下一点的位置。如果约定尝试的顺序为上、右、下、 左(即顺时针方向),则每尝试一个方向不通时,di 值增1,当d 增至4时,表 示此位置一定不是通路上的点,从栈中去除。在找到出口时,栈中保存的就是一 条迷宫通路。
move[4] 0 1
x y int j; // int di; //di }st[MaxSize];// int top=-1 方位示意图如下:
(i + U J> 方
位2 图3.方位图
通路:通路上的每一个点有
i=st[t op ].i;j=st[to p].j;di=st[to p].di; // 取栈顶方块
if (i==xe && j==ye) //找到了出口,输出路径
{
printf("
迷宫路径如下:\n");
for (k=0;k<=t op ;k++) {
prin tf("\t(%d,%d)",st[k].i,st[k].j); if ((k+1)%5==0)
//每输出每5个方块后换一行
prin tf("\n");
} prin tf("\n"); return(1);
}
②否则,找下一个可走的相邻方
块若不存在这样的路径, 说明当前的路径不可能 走通,也就是恢复当前方块为0后退栈。若存在这样的方块,则其方位保存在栈 顶元素中,并将这个可走的相邻方块进栈(其初始位置设置为 -1)
求迷宫回溯过程如图4所示
}
(1)下面介绍求解迷宫(xi,yj )到终点(xe,ye )的路径的函数:先将入口进 栈(其初始位置设置为一1),在栈不空时循环一一取栈顶方块(不退栈)①若该 方块为出口,输出所有的方块即为路径,其代码和相应解释如下:
int mgp ath(i nt xi,i nt yi,i nt xe,i nt ye)
为:(xi,yi)->(xe,ye)
{
struct {
int i; int j; int di;
} st[MaxSize]; int top=-1; int i,j,k,di,fi nd; top++;
st[to p].i=xi;st[t op ].j=yi; st[to p].di=-1;mg[1][1]=-1; while (to p>-1) {
// //
// // 求 解 路 径
当前方块的行号 当前方块的列号
//di 是下一可走方位的方位号 //定义栈 //初始化栈指针
初始方块进栈 //栈不空时循环 //找到一条路径后返回1
圏斗.堆宫回罔过;程示意图
从前一个方块找到相邻可走方块之后, 再从当前方块找在、 的方快,说明当前方块不可能是从入口路径到出口路径的一个方块,
一个方
相邻可走方块,若没有这样 则
从当前方块回溯到前
i,j )已经进栈,在试探
fin d=0;
while (di<4 && fin d==0) {
di++; switch(di) {
case 0:i=st[t op ].i-1;j=st[t op ].j;break;
case 1:i=st[t op ].i;j=st[t op ].j+1;break; case 2:i=st[t op ].i+1;j=st[t op ].j;break; case 3:i=st[t op ].i,j=st[t op ].j-1;break; }
if (mg[i][j]==0) fin d=1;//
找到下一个可走相邻方块
}
if (fin d==1) {
st[t op ].di=di; top++;
//找下一个可走方块 〃找到了下一个可走方块 〃修改原栈顶元素的di 值 〃下一个可走方块进栈
维婪直找耳fe 路泾