迷宫问题的求解数据结构课程设计Word格式文档下载.docx
- 文档编号:20474493
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:25
- 大小:434.39KB
迷宫问题的求解数据结构课程设计Word格式文档下载.docx
《迷宫问题的求解数据结构课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《迷宫问题的求解数据结构课程设计Word格式文档下载.docx(25页珍藏版)》请在冰豆网上搜索。
自2012年2月20日至2012年3月2日共2周
设计依据、要求及主要内容(可另加附页):
设计要求:
设计内容:
输入一个任意大小的迷宫数据,设置入口、出口及障碍,借助栈结构求解走出迷宫的路径并输出。
逻辑设计:
对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据结构为中心的原则划分模块,定义主程序模块和各抽象数据类型。
逻辑设计的结果应写出每个抽象数据类型的定义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法,并画出模块之间的调用关系图;
详细设计:
定义相应的存储结构并写出各函数的伪码算法。
在这个过程中,要综合考虑系统功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基本操作的规格说明尽可能明确具体。
详细设计的结果是对数据结构和基本操作做出进一步的求精,写出数据存储结构的类型定义,写出函数形式的算法框架;
程序编码:
把详细设计的结果进一步求精为程序设计语言程序。
同时加入一些注解和断言,使程序中逻辑概念清楚;
程序调试与测试:
采用自底向上,分模块进行,即先调试低层函数。
能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。
调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果;
结果分析:
程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。
算法的时间、空间复杂性分析;
编写课程设计报告;
以上要求中前三个阶段的任务完成后,先将设计说明数的草稿交指导老师面审,审查合格后方可进入后续阶段的工作。
设计工作结束后,经指导老师验收合格后将设计说明书打印装订,并进行答辩。
指导教师(签字):
教研室主任(签字):
批准日期:
年月日
摘要
由计算机解迷宫时,通常用的是穷举求解的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;
否则沿原路反回,换一个方向继续探索,直至所有可行的通路都探索到为止。
为了保证在任何位置上都能沿原路返回,显然需要用一个后进先出的结构来保存从入口到当前位置的路径。
显然要用到栈。
关键词:
迷宫;
穷举;
栈;
4流程图·
·
6
6程序测试与运行过程·
19
6.1程序调试·
6.2程序运行过程·
1课题描述
本课程设计是解决迷宫求解的问题,从入口出发,顺某一方向向前探索,若能走通,则继续往前走;
否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止。
为了保证在任何位置上都能沿原路退回,显然需要用一个后进先出的结构来保存从入口到当前位置的路径。
因此,在求迷宫通路的算法中要应用“栈”的思想假设“当前位置”指的是“在搜索过程中的某一时刻所在图中某个方块位置”,则求迷宫中一条路径的算法的基本思想是:
若当前位置“可通”,则纳入“当前路径”,并继续朝“下一位置”探索,即切换“下一位置”为“当前位置”,如此重复直至到达出口;
若当前位置“不可通”,则应顺着“来向”退回到“前一通道块”,然后朝着除“来向”之外的其他方向继续探索;
若该通道块的四周4个方块均“不可通”,则应从“当前路径”上删除该通道块。
所谓“下一位置”指的是当前位置四周4个方向(东、南、西、北)上相邻的方块。
假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。
由此,“纳入路径”的操作即为“当前位置入栈”;
“从当前路径上删除前一通道块”的操作即为“出栈”。
2问题分析和任务定义
根据课设题目要求,拟将整体程序分为四大模块。
以下是四个模块的大体分析:
1建立迷宫:
要建立迷宫首先就要建立存储结构,这里我用数组的方式建立的。
根据用户输入的迷宫的大小(我设置的最大值为25可以根据要求调解);
2设置迷宫:
这里将0设置围墙,1是可以通过的路径,-1是不可以通过路径,外墙是以设计好的,内墙需要用户来设置,障碍的难度可自行定义;
3寻找路径:
寻找路径我设置了四个方向{0,1},{1,0},{0,-1},{-1,0}移动方向,依次为东南西北,首先向东走,若不成功则转换方向,成功则继续前进,将走过的路径进行标记,然后存入栈中;
4输出结果:
输出的结果分为两种,一种是用户建立的迷宫主要是让用户检查是否符合要求,第二种输出的是寻找完后的路径,路径用1234·
来表示。
3数据结构分析
3.1存储结构
定义一个整型数组PosType用来存储行列的值。
typedefstruct//栈的元素类型
{
intord;
//通道块在路径上的"序号"
PosTypeseat;
//通道块在迷宫中的"坐标位置"
intdi;
//从此通道块走向下一通道块的"方向"(0~3表示东~北)
}SElemType;
栈的存储结构:
#defineSTACK_INIT_SIZE10//存储空间初始分配量
#defineSTACKINCREMENT2//存储空间分配增量
//栈的顺序存储表示
typedefstructSqStack
SElemType*base;
//在栈构造之前和销毁之后,base的值为NULL
SElemType*top;
//栈顶指针
intstacksize;
//当前已分配的存储空间,以元素为单位
}SqStack;
//顺序栈
3.2算法描述
1.栈的基本操作的算法,简单算法说明如下:
StatusInitStack(SqStack*S)
{//构造一个空栈S,为栈底分配一个指定大小的存储空间
(*S).base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
(*S).base)exit(0);
(*S).top=(*S).base;
//栈底与栈顶相同表示一个空栈
(*S).stacksize=STACK_INIT_SIZE;
return1;
}
StatusStackEmpty(SqStackS)
{//若栈S为空栈(栈顶与栈底相同的),则返回1,否则返回0。
if(S.top==S.base)return1;
elsereturn0;
}
StatusPush(SqStack*S,SElemTypee)
{//插入元素e为新的栈顶元素。
if((*S).top-(*S).base>
=(*S).stacksize){//栈满,追加存储空间
(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
*((*S).top)++=e;
StatusPop(SqStack*S,SElemType*e)
{//若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;
否则返回0。
if((*S).top==(*S).base)return0;
*e=*--(*S).top;
1.查找路径的算法,简单算法说明如下:
StatusMazePath(PosTypestart,PosTypeend)
{//若迷宫maze中存在从入口start到出口end的通道,则求得一条
//存放在栈中(从栈底到栈顶),并返回1;
否则返回0
InitStack(&
S);
curpos=start;
curstep=1;
do
{
if(Pass(curpos)){//当前位置可以通过,即是未曾走到过的通道块
FootPrint(curpos);
//留下足迹
e=(curstep,curpos,1);
Push(&
S,e);
//入栈当前位置及状态
if(curpos.x==end.x&
&
curpos.y==end.y)//到达终点(出口)
return1;
curpos=NextPos(curpos,e.di);
}
else{//当前位置不能通过
if(!
StackEmpty(S)){
Pop(&
S,&
e);
//退栈到前一位置
curstep--;
//前一位置处于最后一个方向(北)
while(e.di==3&
!
StackEmpty(S))
{
MarkPrint(e.seat);
Pop(&
//留下不能通过的标记(-1),退回一步
}
if(e.di<
3){//没到最后一个方向(北)
e.di++;
Push(&
//换下一个方向探索
curpos=NextPos(e.seat,e.di);
//设定当前位置是该新方向上的相邻块
}
}while(!
StackEmpty(S));
return0;
4.流程图
4.1建立迷宫构造空栈函数并判断,若是则建立迷宫,否则返回并构造空栈。
n
y
图3.1建立迷宫函数流程图
4.2设置迷宫先设置迷宫障碍和起点与终点坐标,障碍设为0,用printf函数输出
图3.2设置迷宫函数的流程图
4.3寻找路径先输入起点与终点坐标。
判断,若能通过则留下足迹,入栈,足迹加一并继续判断,若不能,则换方向继续判断。
N
N
Y
图3.3寻找路径函数流程图
4.4输出结果
图3.4输出结果流程图
5程序编码
#include<
stdio.h>
stdlib.h>
string.h>
malloc.h>
//迷宫坐标位置类型
typedefstruct
intx;
//行值
inty;
//列值
}PosType;
#defineMAXLENGTH25//设迷宫的最大行列为25
typedefintMazeType[MAXLENGTH][MAXLENGTH];
//迷宫数组[行][列]
//全局变量
MazeTypem;
//迷宫数组
intcurstep=1;
//当前足迹,初值为1
//构造一个空栈S
intInitStack(SqStack*S)
//为栈底分配一个指定大小的存储空间
(*S).base)
exit(0);
//若栈S为空栈(栈顶与栈底相同的),则返回1,否则返回0。
intStackEmpty(SqStackS)
if(S.top==S.base)
return1;
else
return0;
//插入元素e为新的栈顶元素。
intPush(SqStack*S,SElemTypee)
=(*S).stacksize)//栈满,追加存储空间
(*S).base=(SElemType*)realloc((*S).base,
((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
exit(0);
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;
intPop(SqStack*S,SElemType*e)
if((*S).top==(*S).base)
//这个等式的++*优先级相同,但是它们的运算方式,是自右向左
//定义墙元素值为0,可通过路径为1,不能通过路径为-1,通过路径为足迹
//当迷宫m的b点的序号为1(可通过路径),return1;
否则,return0。
intPass(PosTypeb)
{
if(m[b.x][b.y]==1)
voidFootPrint(PosTypea)//使迷宫m的a点的序号变为足迹(curstep),表示经过
m[a.x][a.y]=curstep;
//根据当前位置及移动方向,返回下一位置
PosTypeNextPos(PosTypec,intdi)
PosTypedirec[4]={{0,1},{1,0},{0,-1},{-1,0}};
//{行增量,列增量}
//移动方向,依次为东南西北
c.x+=direc[di].x;
c.y+=direc[di].y;
returnc;
//使迷宫m的b点的序号变为-1(不能通过的路径)
voidMarkPrint(PosTypeb)
m[b.x][b.y]=-1;
//若迷宫maze中存在从入口start到出口end的通道,则求得一条
否则返回0
intMazePath(PosTypestart,PosTypeend)
{
SqStackS;
PosTypecurpos;
SElemTypee;
if(Pass(curpos))
{//当前位置可以通过,即是未曾走到过的通道块
e.ord=curstep;
e.seat.x=curpos.x;
e.seat.y=curpos.y;
e.di=0;
curstep++;
//足迹加1
else
{//当前位置不能通过
{
while(e.di==3&
StackEmpty(S))//前一位置处于最后一个方向(北)
MarkPrint(e.seat);
//留下不能通过的标记(-1)
Pop(&
//退回一步
curstep--;
3)//没到最后一个方向(北)
//换下一个方向探索
Push(&
curstep++;
//设定当前位置是该新方向上的相邻块
//输出迷宫的结构
voidPrint(intx,inty)
inti,j;
for(i=0;
i<
x;
i++)
for(j=0;
j<
y;
j++)
printf("
%3d"
m[i][j]);
printf("
\n"
);
voidmain()
PosTypebegin,end;
inti,j,x,y,x1,y1,n,k;
do{
system("
cls"
//清屏函数
printf("
<
<
welcome>
>
\n\n\n"
1请输入迷宫的行数,列数(包括外墙)\n"
2请输入迷宫内墙单元数\n"
3迷宫结构如下\n"
4输入迷宫的起点和终点\n"
5输出结果\n"
0退出\n"
\n\n请选择"
scanf("
%d"
&
n);
switch(n)
case1:
printf("
请输入迷宫的行数,列数(包括外墙):
(空格隔开)"
%d%d"
&
x,&
y);
for(i=0;
i++)//定义周边值为0(同墙)
{
m[0][i]=0;
//迷宫上面行的周边即上边墙
m[x-1][i]=0;
//迷宫下面行的周边即下边墙
for(j=1;
y-1;
m[j][0]=0;
//迷宫左边列的周边即左边墙
m[j][y-1]=0;
//迷宫右边列的周边即右边墙
for(i=1;
x-1;
for(j=1;
m[i][j]=1;
//定义通道初值为1
}break;
case2:
{printf("
请输入迷宫内墙单元数:
"
j);
请依次输入迷宫内墙每个单元的行数,列数:
(空格隔开)\n"
for(i=1;
=j;
scanf("
x1,&
y1);
m[x1][y1]=0;
case3:
{Print(x,y);
输入0退出"
scanf("
k);
}break;
case4:
{printf("
请输入起点的行数,列数:
begin.x,&
begin.y);
请输入终点的行数,列数:
end.x,&
end.y);
case5:
if(MazePath(begin,end))//求得一条通路
此迷宫从入口到出口的一条路径如下:
Print(x,y);
//输出此通路
此迷宫没有从入口到出口的路径\n"
}while(n!
=0);
6程序测试与运行
6.1程序调试
在调试程序是主要遇到一下几类问题:
1.选择存储结构的问题:
刚接到课设题目的时候,我就在想用什么来实现迷宫的存储。
用线性表还是数组,最后综合考虑决定用栈和数组结合的方式来实现,用数组来建立迷宫和输出迷宫,用栈来查找路径并将生成的路径压入到栈中,因为栈有先入后出的优点,所以比较容易实现。
2.如何建立迷宫和怎么设置迷宫的问题:
首先迷宫要有一定的范围怎
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 迷宫 问题 求解 数据结构 课程设计