课程设计走迷宫.docx
《课程设计走迷宫.docx》由会员分享,可在线阅读,更多相关《课程设计走迷宫.docx(22页珍藏版)》请在冰豆网上搜索。
课程设计走迷宫
《数据结构程序设计》
课程设计报告
(走迷宫)
学院:
班级:
学号:
姓名:
指导教师:
完成日期:
目录
1.设计任务………………………………………………3
2.程序的总体设计………………………………………3
3.程序的实现…………………………………………8
4.主函数………………………………………………9
5.测试………………………………………………10
6.心得体会………………………………………………12
7.附件…………………………………………………13
1.设计任务
程序开始运行时显示一个迷宫地图,迷宫中央有一只老鼠,迷宫的右下方有一个粮仓。
游戏的任务是使老鼠走到粮仓处。
要求:
1)迷宫的墙足够结实,老鼠不能穿墙而过;
2)正确检测结果,若老鼠在能走到粮仓处,提示成功,否则提示失败;
3)老鼠形象可辨认,可用键盘操纵老鼠上下左右移动;
2.程序的总体设计
首先,确定迷宫的存储结构,说明位置在迷宫中的行坐标和列坐标。
typedefintStatus;
typedefstruct
{
intr,c;/*迷宫中位置的坐标*/
}PosType;
typedefstruct
{
intm,n;
chararr[RANGE][RANGE];/*用二维数组表示迷宫*/
}MazeType;
第二,确定放入栈中的元素的存储结构,表明通道块在路径上的“序号”,通道块的坐标位置以及下一步要走的方向。
typedefintdirectiveType;
typedefstruct
{
intstep;
PosTypeseat;/*当前位置在迷宫中的坐标*/
directiveTypedi;/*从当前位置走到下一位置的方向*/
}ElemType;
第三,确定栈的存储结构。
typedefstructNodeType
{
ElemTypedata;
structNodeType*next;
}NodeType,*LinkType;
typedefstruct
{
LinkTypetop;/*链栈的顶点定义*/
intsize;
}Stack;
voidInitStack(Stack&S)/*构建一个空栈*/
{
S.top=NULL;
S.size=0;
}
StatusMakeNode(LinkType&p,ElemTypee)
{
p=(NodeType*)malloc(sizeof(NodeType));
if(!
p)returnFALSE;/*存储分配失败*/
p->data=e;
p->next=NULL;
returnTRUE;
}
定义在什么情况下要入栈
StatusPush(Stack&S,ElemTypee)
{
LinkTypep;
if(MakeNode(p,e))
{
p->next=S.top;
S.top=p;
S.size++;
returnTRUE;
}
returnFALSE;
}
判断栈是否为空
StatusStackEmpty(StackS)/*若栈为空栈,则返回TRUE,否则返回FALSE*/
{
if(S.top==NULL)
returnTRUE;
returnFALSE;
}
定义在什么情况下要出栈
StatusPop(Stack&S,ElemType&e)
{
LinkTypep;
if(StackEmpty(S))
returnFALSE;
else
{
p=S.top;
S.top=S.top->next;
e=p->data;
S.size--;
free(p);
returnTRUE;
}
}
定义什么情况下迷宫可以走
Statuspass(MazeTypemaze,PosTypecurpos)
{
intm,n;
m=curpos.r;
n=curpos.c;
if(maze.arr[m][n]=='')
returnTRUE;
returnFALSE;
}
定义什么情况下已经走出了迷宫
StatusSame(PosTypecurpos,PosTypeend)
{
if(curpos.r==end.r&&curpos.c==end.c)
returnTRUE;
returnFALSE;
}
定义走通的位置要用*标记
voidFootPrint(MazeType&maze,PosTypecurpos)
{
intm,n;
m=curpos.r;
n=curpos.c;
maze.arr[m][n]='*';
}
定义在探索过程中老鼠走的方向关系
PosTypeNextPos(PosTypecurpos,intdi)
{
switch(di)
{
case1:
curpos.c++;
break;
case2:
curpos.r++;
break;
case3:
curpos.c--;
break;
case4:
curpos.r--;
break;
}
returncurpos;
}
定义走过但没有走通位置要用@标记
voidMarkPrint(MazeType&maze,PosTypep)
{
maze.arr[p.r][p.c]='@';
}
voidPrintMaze(MazeTypema)
{
inti,j;
printf("\n");
for(i=0;i{
printf("\t");
for(j=0;j{
printf("%c",ma.arr[i][j]);
}
printf("\n");
}
printf("\n");
}
将数组转化为迷宫
voidInitMaze(MazeType&maze,inta[M][N],introw,intcol)
{
inti,j;
maze.m=row;
maze.n=col;
for(i=0;ifor(j=0;j
{
if(a[i][j]==0)
maze.arr[i][j]='';
else
maze.arr[i][j]='#';
}
}
探索迷宫
StatusMazePath(MazeType&maze,PosTypestart,PosTypeend)
{
Stacks;
intcurstep=1;//探索第一步
Statusfound=FALSE;
ElemTypee;
PosTypecurpos=start;//设定当前位置为入口
InitStack(s);
do{
if(pass(maze,curpos))//当前位置可以通过,即是未曾走过的通道块
{
FootPrint(maze,curpos);//留下足迹
{
e.step=curstep;
e.seat=curpos;
e.di=1;
}
Push(s,e);//加入路径
if(Same(curpos,end))//到达终点
{
found=TRUE;
}
else
{
curpos=NextPos(curpos,1);//下一位置是当前位置的北邻
curstep++;//探索下一步
}
}
else//当前位置不能通过
if(!
StackEmpty(s))
{
Pop(s,e);
while((e.di==4)&&!
StackEmpty(s))
{
MarkPrint(maze,e.seat);//留下不能通过的标记,并退回一步
Pop(s,e);
curstep--;
}
if(e.di<4)
{
e.di++;
Push(s,e);//探索下一方向
curpos=NextPos(e.seat,e.di);//设定当前位置是该新方向上的相邻块
}
}
}while(!
StackEmpty(s)&&!
found);
returnfound;
}
voidPrint(intmaze[][N])
{
inti,j;
printf("表示迷宫的数组\n");
for(i=0;i{
printf("\t");
for(j=0;j{
printf("%d",maze[i][j]);
}
printf("\n");
}
printf("\n");
}
3.程序的实现
标记入口位置(说明此位置已试探),把入口压入栈中
栈非空
栈非空
取栈顶元素
初始试探方向
存在试探方向
确定试探位置的坐标
试探位置是否为迷宫出口
打印路径上每个位置
是否为通道
标记该位置
换个方向试探
返回
该位置及方向进栈
前进到下一位置
C++
方向向东
r++
方向向南
C--
方向向西
r--
方向向北
r--
c--
位置
(c,r)
c++
r++
4.主函数设计
voidmain()
{
intmaze[M][N]={输出迷宫数组
1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,1,1,1,0,0,1,
1,0,0,0,0,0,1,0,0,1,1,
1,0,1,1,1,0,0,0,1,1,1,
1,0,0,0,1,0,1,1,0,1,1,
1,1,0,0,1,0,1,1,0,0,1,
1,1,1,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1};
MazeTypeL;
PosTypestart,end;
Print(maze);
InitMaze(L,maze,M,N);
start.r=2;定义迷宫入口和出口
start.c=4;
end.r=6;
end.c=9;
printf("由数组转化出的迷宫");
PrintMaze(L);
if(MazePath(L,start,end))
printf("迷宫的路径,用*表示");
else
printf("此迷宫没有通路!
");
PrintMaze(L);
}
5.测试
第一次测试
start.r=2;
start.c=4;
end.r=6;
end.c=9;
第二个测试
start.r=1;
start.c=1;
end.r=6;
end.c=9
6.心得体会
数据结构是在整个计算机科学与技术领域上广泛被使用的术语。
它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。
数据结构有逻辑上的数据结构和物理上的数据结构之分。
逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。
数据结构是数据存在的形式。
数据结构是信息的一种组织方式,其目的是为了提高算法的效率,它通常与一组算法的集合相对应,通过这组算法集合可以对数据结构中的数据进行某种操作。
数据结构课程的主要目的是介绍一些常用的数据结构,阐明数据结构内在的逻辑关系,讨论它们在计算机中的存储表示,并结合各种数据结构,讨论对它们实行的各种运算的实现算法。
通过这次数据结构课程设计,让我学到了好多东西。
在实际操作过程中犯了一些错误却让我有了意外的收获,所学数据结构理论知识得到了巩固。
通过实际操作,学会数据结构程序编程的基本步骤、基本方法,开发了自己的逻辑思维能力,培养了分析问题、解决问题的能力。
现在终于挨到了写收获与体会的时候了,的确令人兴奋,看看自己的劳动成果,好开心。
一个星期前的现在,当听到老师布置给我们的题目时,我们都蒙了,这么难的题目我们怎么会啊,但我们只能尽我们自己最大的努力把程序给写出来,虽然知道这一路肯定是异常的艰苦,但豁出去了。
上网查资料、去图书馆查,查相关的函数,经过两三天的努力,我把框架弄出来了,可是还有计算难题摆在我的面前,真的是个难题,自从把框架弄好了以后就没有进展了,眼看一个星期快过去了,我那个急啊,可是急也没有用。
我坚持,终于工夫不负有心人,我参照类似程序,改改和添添,终于大功告成,我们欢呼我们雀跃,终于相信我们自己是足够的伟大。
7.附件
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
#defineRANGE20
#defineM8
#defineN11
typedefintStatus;
typedefstruct
{
intr,c;
}PosType;
typedefstruct
{
intm,n;
chararr[RANGE][RANGE];
}MazeType;
typedefintdirectiveType;
typedefstruct
{
intstep;
PosTypeseat;
directiveTypedi;
}ElemType;
typedefstructNodeType
{
ElemTypedata;
structNodeType*next;
}NodeType,*LinkType;
typedefstruct
{
LinkTypetop;
intsize;
}Stack;
voidInitStack(Stack&S)
{
S.top=NULL;
S.size=0;
}
StatusMakeNode(LinkType&p,ElemTypee)
{
p=(NodeType*)malloc(sizeof(NodeType));
if(!
p)returnFALSE;
p->data=e;
p->next=NULL;
returnTRUE;
}
StatusPush(Stack&S,ElemTypee)
{
LinkTypep;
if(MakeNode(p,e))
{
p->next=S.top;
S.top=p;
S.size++;
returnTRUE;
}
returnFALSE;
}
StatusStackEmpty(StackS)
{
if(S.top==NULL)
returnTRUE;
returnFALSE;
}
StatusPop(Stack&S,ElemType&e)
{
LinkTypep;
if(StackEmpty(S))
returnFALSE;
else
{
p=S.top;
S.top=S.top->next;
e=p->data;
S.size--;
free(p);
returnTRUE;
}
}
Statuspass(MazeTypemaze,PosTypecurpos)
{
intm,n;
m=curpos.r;
n=curpos.c;
if(maze.arr[m][n]=='')
returnTRUE;
returnFALSE;
}
StatusSame(PosTypecurpos,PosTypeend)
{
if(curpos.r==end.r&&curpos.c==end.c)
returnTRUE;
returnFALSE;
}
voidFootPrint(MazeType&maze,PosTypecurpos)
{
intm,n;
m=curpos.r;
n=curpos.c;
maze.arr[m][n]='*';
}
PosTypeNextPos(PosTypecurpos,intdi)
{
switch(di)
{
case1:
curpos.c++;
break;
case2:
curpos.r++;
break;
case3:
curpos.c--;
break;
case4:
curpos.r--;
break;
}
returncurpos;
}
voidMarkPrint(MazeType&maze,PosTypep)
{
maze.arr[p.r][p.c]='@';
}
voidPrintMaze(MazeTypema)
{
inti,j;
printf("\n");
for(i=0;i{
printf("\t");
for(j=0;j{
printf("%c",ma.arr[i][j]);
}
printf("\n");
}
printf("\n");
}
voidInitMaze(MazeType&maze,inta[][N],introw,intcol)
{
inti,j;
maze.m=row;
maze.n=col;
for(i=0;ifor(j=0;j
{
if(a[i][j]==0)
maze.arr[i][j]='';
else
maze.arr[i][j]='#';
}
}
StatusMazePath(MazeType&maze,PosTypestart,PosTypeend)
{
Stacks;
intcurstep=1;
Statusfound=FALSE;
ElemTypee;
PosTypecurpos=start;
InitStack(s);
do{
if(pass(maze,curpos))
{
FootPrint(maze,curpos);
{
e.step=curstep;
e.seat=curpos;
e.di=1;
}
Push(s,e);
if(Same(curpos,end))
{
found=TRUE;
}
else
{
curpos=NextPos(curpos,1);
curstep++;
}
}
else
if(!
StackEmpty(s))
{
Pop(s,e);
while((e.di==4)&&!
StackEmpty(s))
{
MarkPrint(maze,e.seat);
Pop(s,e);
curstep--;
}
if(e.di<4)
{
e.di++;
Push(s,e);
curpos=NextPos(e.seat,e.di);
}
}
}while(!
StackEmpty(s)&&!
found);
returnfound;
}
voidPrint(intmaze[][N])
{
inti,j;
printf("表示迷宫的数组\n");
for(i=0;i{
printf("\t");
for(j=0;j{
printf("%d",maze[i][j]);
}
printf("\n");
}
printf("\n");
}
voidmain()
{
intmaze[M][N]={
1,1,1,1,1,1,1,1,1,1,1,
1,0,1,0,0,1,1,1,0,0,1,
1,0,0,0,0,0,1,0,0,1,1,
1,0,1,1,1,0,0,0,1,1,1,
1,0,0,0,1,0,1,1,0,1,1,
1,1,0,0,1,0,1,1,0,0,1,
1,1,1,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1};
MazeTypeL;
PosTypestart,end;
Print(maze);
InitMaze(L,maze,M,N);
start.r=2;
start.c=4;
end.r=6;
end.c=9;
printf("由数组转化出的迷宫");
PrintMaze(L);
if(MazePath(L,start,end))
printf("迷宫的路径,用*表示");
else
printf("此迷宫没有通路!
");
PrintMaze(L);
}
|
|