迷宫问题的求解
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3,3,0
栈中每一组数据是所到 哪个方向向下走的,对于图
3,2,1 2,2,0 达的每点的坐标及从该点沿 2,1,1
1,1,0
hing at a time and All things in their being are good for somethin
3 迷宫,走的路线为:(1,1)0(2,1)1(2,2)0(3,2)1(3,3)0(3,4)0(下 脚标表示方向),当无路可走,则应回溯,对应的操作是出栈,沿下一个方向即 方向继续试探。
径可走结点
top--;
i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;
}
find=0;
while (di<4 && find==0) //找下一个可走结点
{ di++;
switch(di)
{
case 0:i=Stack[top].i-1;j=Stack[top].j;break;
栈中元素是一个由行、列、方向组成的三元组,栈元素的设计如下:
typedef struct{ int x , y , d ;/* 横纵坐标及方向*/
}datatype ; 栈的定义为: SeqStack s ; iv、达某点,以避免发生死循环: 一种方法是另外设置一个标志数组 mark[m][n],它的所有元素都初始化为 0,一旦到达了某一点 ( i , j )之后,使 mark[ i ][ j ] 置 1,下次再试探 这个位置时就不能再走了。另一种方法是当到达某点(i , j)后使 maze[ i ] [ j ] 置 -1,以便区别未到达过的点,同样也能起到防止走重复点的目的,此 处采用后一方法,算法结束前可恢复原迷宫。 3、 详细设计
//找到了出口,输出路径
{
printf("%4d: ",count++);
for (k=0;k<=top;k++)
{
//以三元组输出路径
printf("(%d,%d,%d) ",Stack[k].i,Stack[k].j,Stack[k].di);
if ((k+1)%5==0) printf("\n\t");
i=x+move[d].x ; j=y+move[d].y ; if ( maze[i][j]= =0 ) {
temp={x, y, d} ; Push_SeqStack ( s, temp ) ; x=i ; y=j ; maze[x][y]= -1 ; if (x= =m&&y= =n) return 1 ; /*迷宫有路*/ else d=0 ; } else d++ ; } /*while (d<4)*/ } /*while (! Empty_SeqStack (s ) )*/ return 0 ;/*迷宫无路*/ } 栈中保存的就是一条迷宫的通路。 4、 测试与分析
6、 附录:源代码清单
非递归
#include <stdio.h>
#include <string>
#define M 9
//行数
#define N 8
//列数
#define MaxSize 100
//栈最多元素个数
int mg[M+2][N+2] = {
//迷宫测试数据矩阵,左上角(1,1)为
入口,右下角(9,8)为出口
走结点进栈
mg[i][j]=-1;
//避免重复走到该结点
}
else
//没有路径可走,则退栈
{
mg[Stack[top].i][Stack[top].j]=0;
//让该位置变为其他路
径可走结点
top--;
}
}
printf("最短路径如下:\n");
printf("长度: %d\n",minlen);
//输出时每 5 个结
点换一行
}
printf("\n");
if (top+1<minlen)
//比较找最短路径
{
for (k=0;k<=top;k++)
Path[k]=Stack[k];
minlen=top+1;
}
mg[Stack[top].i][Stack[top].j]=0; //让该位置变为其他路
2、 概要设计 i)设计中非递归程序的模块结构图 图中方框表示函数,方框中指出函数名,箭头方向表示函数间的调用关系,虚 线方框表示文件的组成
hing at a time and All things in their being are good for somethin
main()
mapath(
)
mgpath():求解迷宫问题,即输出从(1,1)到(M,N)的全部路径和最短 路径(包含最短路径长度)。当找到一条路径时,不使用 return 语句退出,而 是出栈一次,重新回溯走另一条路径,并用 minlen 记录最短路径长度,Path 数组记录最短路径。
ii)程序的数据结构和数据库结构分析 设迷宫为 m 行 n 列,利用 maze[m][n]来表示一个迷宫,maze[i][j]=0 或 1;
int top=-1;
//栈顶指针
int count=1;
//路径数计数
int minlen=MaxSize;
//最短路径长度
void mgpath()
//路径为:(1,1)->(M,N)
{
int i,j,di,find,k;
hing at a time and All things in their being are good for somethin
while (! Empty_SeqStack (s ) ) { Pop_SeqStack (s,&temp) ;
hing at a time and All things in their being are good for somethin
x=temp.x ; y=temp.y ; d=temp.d+1 ; while (d<4) {
① 输入输出的要求: ② (i) 求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一
个坐标,d 表示走到下一个坐标的方向。 (ii)输出迷宫示意图
③ 程序所能达到的功能: (i) 实现一个以链表作存储结构的栈类型,以非递归算法求取所有通路和最短路 径 (ii)以一个递归算法,对任意输入的迷宫矩阵(1 代表不通,0 代表通路)求出所 有通路
top++;
//进栈
Stack[top].i=1;
Stack[top].j=1;
Stack[top].di=-1;mg[1][1]=-1; //初始结点进栈
while (top>-1)
//栈不空时循环
{
i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;
if (i==M && j==N)
伪码设计 (1) 栈初始化; (2) 将入口点坐标及到达该点的方向(设为-1)入栈 (3) while (栈不空) { 栈顶元素=>(x , y , d) 出栈 ; 求出下一个要试探的方向 d++ ; while (还有剩余试探方向时) { if (d 方向可走) 则 { (x , y , d)入栈 ; 求新点坐标 (i, j ) ; 将新点(i , j)切换为当前点(x , y) ; if ( (x ,y)= =(m,n) ) 结束 ; else 重置 d=0 ;
case 3:i=Stack[top].i,j=Stack[top].j-1;break;
}
if (mg[i][j]==0) find=1;
}
if (find==1)
//找到了下一个可走结点
{ Stack[top].di=di; //修改原栈顶元素的 di 值
top++;Stack[top].i=i;Stack[top].j=j;Stack[top].di=-1;//下一个可
} else d++ ; } } 算法如下: int path(int &maze,int m, int n, int move) //m,n 为 maze 的一、二维长度,move 为结构体数组存放了试探的 4 个方向坐标
{ SeqStack s ; datetype temp ; int x, y, d, i, j ; temp.x=1 ; temp.y=1 ; temp.d=-1 ; Push_SeqStack (s,temp) ;阿
hing at a time and All things in their being are good for somethin
case 1:i=Stack[top].i;j=Stack[top].j+1;break;
case 2:i=Stack[top].i+1;j=Stack[top].j;break;
迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出 口。
00100010 00100010 00001101 01110010 00010000 01000101 01111001 11000101 11000000
hing at a time and All things in their being are good for somethin
其中:0 表示通路,1 表示不通,当从某点向下试探时,中间点有 4 个方向可以 试探,(见图)而四个角点有 2 个方向,其它边缘点有 3 个方向,为使问题简单 化我们用 maze[m+2][n+2]来表示迷宫,而迷宫的四周的值全部为 1。这样做使 问题简单了,每个点的试探方向全部为 4,不用再判断当前点的试探方向有几 个,同时与迷宫周围是墙壁这一实际问题相一致。
1、 需求分析
(1)问题描述:以一个 m*n 的长方阵表示迷宫,0 和 1 分别表示迷宫中的通路和障碍。设计 一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
(2)基本要求: 1)首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。 求得的通路以三元组(i,j,d)的形式输出。其中:(i,j)指示迷宫中的一个坐标, d 表示走到下一坐标的方向。如,对于教材第 50 页图 3.4 所示的迷宫,输出一条通路 为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),…。 2)编写递归形式的算法,求得迷宫中所有可能的通路。 3)以方阵形式输出迷宫及其通路。 4)按照题意要求独立进行设计,设计结束后按要求写出设计报告。
hing at a time and All things in their being are good for somethin
程序设计与算法综合训练》设计报告 1
学号:E11514064 姓名:汪泓章 年级: 大一 专 业:计科
项目名称:迷宫问题的求解 完成日期:2016 年 6 月 28 日
iii、栈的设计 当到达了某点而无路可走时需返回前一点,再从前图 一3 点增量开数始组向mo下ve一个方向 继续试探。因此,压入栈中的不仅是顺序到达的各点的坐标,而且Leabharlann Baidu要有从前 一点到达本点的方向,即每走一步栈中记下的内容为(行,列,来的方向)。对 于图 1 所示迷宫,依次入栈为:
top — >
3,4, 0
5、 总结 这次的项目,加强了我动手、思考和解决问题的能力。巩固和加深了对 数据结构的理解,提高综合运用本课程所学知识的能力。培养了我选用
hing at a time and All things in their being are good for somethin
参考书,查阅手册及文献资料的能力。培养独立思考,深入研究,分析 问题、解决问题的能力。通过实际编译系统的分析设计、编程调试,掌 握应用软件的分析方法和工程设计方法。
{1,0,1,1,1,1,0,0,1,1},
{1,1,1,0,0,0,1,0,1,1},
{1,1,1,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1}
};
struct
{
int i;int j;int di;
} Stack[MaxSize],Path[MaxSize]; //定义栈和存放最短路径的数组
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,1,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,1,1},
{1,0,1,1,1,0,0,1,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,1,1},