迷宫与栈问题文档格式.docx
《迷宫与栈问题文档格式.docx》由会员分享,可在线阅读,更多相关《迷宫与栈问题文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
8
测试主函数迷宫的输入输出
测试迷宫函数和迷宫路径输出函数
五、
总结
9
六、
附件(代码)
一、系统开发的背景
迷宫问题是心理学中的一个经典问题,一直以来人们乐都此不彼的研究它。
同样利用栈的思想也可以解决迷宫问题。
二、系统分析与设计
(一)系统功能要求
以一个mXn的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。
设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。
求得的通路以三元组(i,j,d)的形式输出。
其中:
(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。
(二)系统模块结构设计
通过对系统功能的分析,系统功能如图1所示。
图1迷宫与栈问题系统功能图
通过上图的功能分析,把整个系统划分为4个模块:
1、栈的基本操作:
该模块主要包括栈的初始化、栈空判别算法、入栈算法、出栈算法;
主要通过函数SeqStack*Init_SeqStack()、Empty_SeqStack(SeqStack*s)、Push_SeqStack(SeqStack*s,DateTypex)、pop_SeqStack(SeqStack*s,DateType*x)实现;
2、迷宫算法:
该模块主要通过函数path(SeqStack*s)实现,
3、迷宫路径输出算法:
该模块主要通过函数printpath(SeqStack*s)实现;
4、主函数:
该模块主要是迷宫的输入、打印,以及对以上函数的调用。
三、系统的设计与实现
(一)栈的基本操作
分析:
栈的初始化算法也可理解为置空栈算法:
首先建立栈空间,然后初始化栈顶指针。
利用if来判断是否申请到足够大的储存空间,然后返回空指针或栈空间地址;
栈空判别算法:
当栈顶指针指向栈底时,栈为空;
入栈算法:
入栈时,首先借助if语句判断栈是否满了,栈满时,不能入栈,返回错误代码0,相反,栈顶指针向上移动,将x置于新的栈顶,入栈成功返回成功代码1;
出栈算法:
出栈时,首先判断栈是否为空,借助于if语句,栈空不能出栈,返回错误代码0,相反,保存栈顶元素值,栈顶指针向下移动,栈顶元素存入*x,返回成功代码1;
该模块如图2所示:
图2栈的基本操作
该模块的具体代码如下所示:
//栈的初始化算法
SeqStack*Init_SeqStack(){
SeqStack*s;
s=(SeqStack*)malloc(sizeof(SeqStack));
s->
top=0;
returns;
}
//栈空判别算法
intEmpty_SeqStack(SeqStack*s){
if(s->
top==0)
//判断空栈
return1;
else
return0;
//入栈算法
intPush_SeqStack(SeqStack*s,DateTypex){
top==Maxsize-1)
//判断栈满
else{
top++;
data[s->
top]=x;
//出栈算法
intpop_SeqStack(SeqStack*s,DateType*x){
if(Empty_SeqStack(s))
*x=s->
top];
top--;
(二)迷宫算法:
path(SeqStack*s)
从迷宫入口出发,按照一定的顺序(在本程序中顺序依次为右、右下、下、左下、左、左上,上、右上)对周围的墙、路进行判断;
若周围的位置都为1(即没有通路),则沿原路返回前一点,换下一个方向继续试探,直到所有通路都试探到,或找到一条通路,或无路可走又返回到入口点。
在求解过程中,为了保证在到达某一点后不能向前继续行走时,能正确返回前一点,以便继续从下一个方向向前试探,则需要用一个栈保存所能到达的没一点的下标及从该点前进的方向。
栈是由行、列、方向组成的三元组。
迷宫求解算法思想如下:
(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;
d++;
}}
//迷宫算法
intpath(SeqStack*s)
{
DateTypetemp;
intx,y,d,i,j;
temp.x=1;
temp.y=1;
temp.d=-1;
//初始化入口坐标及方向
Push_SeqStack(s,temp);
while(!
Empty_SeqStack(s))
pop_SeqStack(s,&
temp);
x=temp.x;
y=temp.y;
d=temp.d+1;
while(d<
8)
i=x+move[d].x;
j=y+move[d].y;
if(maze[i][j]==0)
//该点可达
temp.x=x;
temp.y=y;
temp.d=d;
//坐标及方向
//坐标及方向入栈
x=i;
y=j;
maze[x][y]=-1;
//到达新点
if(x==m&
&
y==n)
//到出口,迷宫有路,成功返回1
d=0;
//重新初始化方向
//改变方向
//迷宫无路,失败返回0
(三)迷宫路径输出算法:
printpath(SeqStack*s)
利用for循环输出栈中保存的路径。
该算法的流程图如图3所示:
图3迷宫路径输出流程图
voidprintpath(SeqStack*s)
inti;
for(i=1;
i<
=s->
top;
i++)
{printf("
{[%d,%d],%d}"
s->
data[i].x,s->
data[i].y,s->
data[i].d);
if(i<
top)
printf("
-->
"
);
if(i%3==0)
\n"
(四)主函数
迷宫的输入输出借助于for循环实现,为了迷宫算法查找方便,用maze[m+2][m+2]来表示迷宫,在四周加上一圈“哨兵”即迷宫四周的值全部为1。
标识迷宫入口和出口即将maze[1][1]、maze[m][n]置为0。
voidmain()
inti,j,k;
~~~~~~~~~~~~~~~~~~~~~~~~~\n"
迷宫与栈问题
\n"
请按行输入迷宫(%d*%d):
m,n);
提示:
0表示通路,1表示阻碍\n"
=m;
for(j=1;
j<
=n;
j++)
scanf("
%ld"
&
maze[i][j]);
maze[1][1]=0;
maze[m][n]=0;
for(i=0;
m+2;
maze[i][0]=1;
maze[i][n+1]=1;
for(j=0;
n+2;
maze[0][j]=1;
maze[m+1][j]=1;
\n输入的迷宫如图所示\n"
{
%2d"
maze[i][j]);
s=Init_SeqStack();
k=path(s);
if(k==1)
{
\n输出路径如下:
printpath(s);
失败!
\n\n"
getchar();
四、系统测试
(一)测试主函数迷宫的输入输出
图4迷宫的输入及打印
(二)测试迷宫函数和迷宫路径输出函数
图5迷宫路径的输出
五、总结
系统完成了迷宫的输入输出及查找路径并输出了路径的功能。
系统不能输出迷宫所有的路径。
统过这段时间的课程设计,我对计算机的应用,数据结构的作用以及C语言的使用都有了更深的了解。
尤其是C语言的进步让我深刻的感受到任何所学的知识都需要实践,没有实践就无法真正理解这些知识以及掌握它们。
在设计此程序时,刚开始感到比较迷茫,然后一步步分析,试着写出基本的算法,思路渐渐清晰,最后完成程序。
当然也遇到不少的问题,也正是因为这些问题引发的思考给我带了收获。
这次课程设计让我更加深入了解很多方面的知识,如顺序结构的栈类型及其基本操作,数组的运用等等。
在实际的上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次课程设计可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。
六、附件(代码)
#include<
stdio.h>
stdlib.h>
#definem10//迷宫的行
#definen10
//迷宫的列
//顺序栈的类型描述
#defineMaxsize50
intmaze[m+2][n+2];
//Move数组定义
typedefstruct{
intx,y;
}item;
itemmove[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
//栈中元素的设计
intx,y,d;
}DateType;
//横坐标及方向
DateTypedata[Maxsize];
inttop;
}SeqStack;
//定义一个指向顺序栈的指针变量
s=(SeqStack*)malloc(sizeof(SeqStack))