数据结构课程设计报告.docx
《数据结构课程设计报告.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告.docx(12页珍藏版)》请在冰豆网上搜索。
数据结构课程设计报告
数学与计算机学院
课程设计说明书
课程名称:
数据结构-课程设计
课程代码:
题目:
迷宫问题
年级/专业/班:
学生姓名:
学 号:
开始时间:
2010年6月21日
完成时间:
2010年7月2日
课程设计成绩:
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书撰写质量(45)
总分(100)
指导教师签名:
年月日
目录
1需求分析1
2程序运行平台2
3概要设计3
4详细设计4
5调试分析7
6测试结果9
7结论14
致谢15
参考文献16
附录17
摘要
本次课程设计分析了计算机求解迷宫路径一般采用的是“穷举求解”的方法,利用栈的思想编程实现了求解迷宫路径的系统,该系统能够输出一个任意的迷宫从指定的入口到出口的所有通路,以及用方阵形式输出迷宫。
关键词:
迷宫路径;穷举求解;栈;方阵形式
1需求分析
(1)以一个m*n的长方阵表示迷宫,0表示通路,1表示障碍,迷宫的四周有一圈障碍。
(2)程序输出的结果以三元组(i,j,di)的形式输出,其中:
(i,j)指示迷宫中的一个坐标,di表示走到下一坐标的方向,di的取值为0、1、2、3分别表示向上、向右、向下、向左。
(3)程序能够输出一个任意的迷宫从指定入口到出口的所有通路,以及以方阵形式输出迷宫。
(4)测试数据:
先由用户输入迷宫的行数和列数,即m和n的值,如:
m=4,n=5;再由用户输入迷宫的信息,当输入的数据不是0或1时设置为1。
设置两个迷宫用来测试,一个有通路的迷宫和没有通路的迷宫,如下:
有通路的迷宫:
01001没有通路的迷宫:
00100
0001110011
1000101100
0000001001
2程序运行平台
操作系统:
WindowsXP、Windows2000等
开发平台:
MicrosoftVisualC++6.0
3概要设计
主函数中的各模块函数如下:
初始化迷宫:
voidInitMaze(MazeType&maze,inta[MAX][MAX],introw,intcol)
输出迷宫信息:
voidPrintMaze(MazeTypemaze,introw,intcol)
得到迷宫信息,直接输入数据:
voidGetMaze(),该函数中调用初始化迷宫的函数和输出迷宫的函数。
求解迷宫所有通路的函数:
voidMazePath(MazeTypemaze,PosTypestart,PosTypeend)
主函数的各函数调用关系如图3-1所示,主函数调用创建迷宫函数和求解所有路径的函数,其中创建迷宫信息的函数调用初始化迷宫和输出迷宫。
图3-1主函数调用各模块函数的关系图
4详细设计
数据类型定义如下:
#defineRANGE20;#defineMAX20;表示迷宫大小。
#defineMAXSIZE100;栈的大小。
typedefstruct{typedefstruct{
intm,n;//行数和列数introw;//行
intarr[RANGE][RANGE];//迷宫数组intcol;//列
}MazeType;//迷宫类型}PosType;//位置类型
MazeTypemaze;PosTypestart;//入口
structPosTypeend;//出口
{inti;//横坐标
intj;//纵坐标
intdi;//方向
}Stack[MaxSize];//栈
inttop=-1;//栈顶指针
intcount=1;//路径数计数
初始化迷宫:
voidInitMaze(MazeType&maze,inta[MAX][MAX],introw,intcol)
{按照用户输入的row行和col列的二维数组(取值0或是1)设置迷宫maze的初值;
加上一圈围墙;
}
输出迷宫信息:
voidPrintMaze(MazeTypemaze,introw,intcol)
{把加上了围墙后的迷宫信息输出;}
得到迷宫的相关数据,直接输入数据:
voidGetMaze()
{输入迷宫的行数和列数;行数ROW,列数COL
输入迷宫信息;a[MAX][MAX]
输入迷宫的入口和出口;入口(start.row,start.col)出口(end.row,end.col)
调用函数InitMaze(maze,a,ROW,COL);
调用函数PrintMaze(maze,ROW,COL);
}
求解迷宫所有通路的函数:
voidMazePath(MazeTypemaze,PosTypestart,PosTypeend)
{inti,j,di,find,k;
top++;//进栈
初始方块进栈即入口(start.row,start.col)进栈,其中di=-1,(表示无方向可走);
while(top>-1)/*栈不空时循环*/
{i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;
if(i==end.row&&j==end.col)/*找到了出口,输出路径*/
{输出迷宫路径;形式(start.row,start.col,di)->(i,j,di),每五个换行。
让该位置变为其他路径可走结点;
出栈:
top--;
赋值:
i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;
}
find=0;
while(di<4&&find==0)/*找下一个可走方块*/
{di++;
switch(di)
{case0:
向上;break;case1:
向右;break;
case2:
向下;break;case3:
向左;break;}
if(mg[i][j]==0)find=1;
}
if(find==1)/*找到了下一个可走方块*/
{修改原栈顶元素的di值;
下一个可走方块进栈;
避免重复走到该方块;}
else
{没有路径可走,则退栈;
让该位置变为其他路径可走方块}
}
}
}
5调试分析
(1)调试过程中遇到的问题的解决,以及程序设计思想的实现:
1)调试过程中出现的错误有编译连接时的一些语法错误,也有由于算法存在问题而导致程序运行没有结果或者不是预期的结果。
这里主要说一下自己由于算法而导致的错误:
因为没有注意结点不能重复走,所以造成了死循环,程序没有结果。
通过分析后把走过的结点变为不可走的结点,这样就避免了重复走到该结点。
还有就是判断迷宫是否有通路的这个结果不能如预期的结果那样:
有通路就输出所有的通路,没有就输出“没有路径可走!
”。
因为没有通路可走的时候栈是空的,但是输出所有的路径以后栈也是空的。
当迷宫有通路的时候,在输出所有路径以后还是会输出“没有路径可走!
”这句话。
当迷宫没有通路的时候,输出“没有路径可走!
”这句话。
因为算法的思想是这样的,所以达不到预期的结果。
解决的方法是如果迷宫有通路则输出所有的通路,如果迷宫没有通路,则没有结果输出。
2)迷宫的求解一般采用的是“穷举求解”,利用栈的思想,先将入口进栈(初始方位设置为-1),在栈不空时循环:
取栈顶方块(不退栈),若该方块是出口,则输出栈中方块即为路径。
否则,找下一个可走的相邻方块,若不存在这样的方块,则退栈。
若存在这样的方块,则将其方位保存到栈顶元素中,并将这个可走的相邻方块进栈(初始方位设置为-1)。
为了保证试探的可走相邻方块不是已走路径上的方块,如(i,j)已进栈,在试探(i+1,j)的下一可走方块时,又试探到(i,j),这样可能会引起死循环,为此,在一个方块进栈后,将对应的迷宫数组元素值改为-1(变为不可走的相邻方块),当退栈时(表示没有可走相邻方块),将其恢复为0。
(2)算法的时空分析和改进思想:
创建迷宫信息的函数的时间复杂度取决于迷宫数组的大小,迷宫大则语句执行次数多,时间复杂度高。
求解迷宫的所有路径的函数的时间复杂度取决于迷宫的路径数,路径数多则时间复杂度就高。
而空间复杂度则是一定的,因为采用的是顺序栈,已经分配好了一个足够的空间。
求解迷宫的所有路径的函数采用的是非递归的方式,可以采用递归的方式求解迷宫的所有路径。
程序还有很多可以改进的地方,如以方阵的形式输出迷宫的通路,这样通路就简单明了。
迷宫的输出形式也可以改进,如有障碍的地方就放一个标识,通路就不放,这样更简洁明白。
(3)经验和体会:
通过这次程序设计,我对于顺序栈的相关知识有了更深刻地理解,对于栈的应用也更深刻地了解。
但是自己由于对于递归这块的知识理解不够,所以在求解迷宫的所有路径时采用的是非递归的方法,采用递归或许要简单些吧。
这次自己在编程过程中遇到了不少的麻烦,而这些造成这些麻烦的原因就是自己的基础知识不牢固,编译的时候出现一些低级的错误,而这些都是应该要避免发生的。
还有当拿到程序要求的时候,开始时头脑里根本就是一片混乱,没有什么思路,后来还是通过看书和在网上查找相关资料,阅读别人的程序后根据自己的理解而写出了程序。
这说明自己还不会分析问题,抓住问题的本质,理清思路。
总归一句话就是自己动手能力差,练习不够。
6测试结果
(1)求解的迷宫有通路的情况:
1)由用户输入了迷宫的行数和列数
2)由用户输入的迷宫数据:
3)用户指定迷宫的入口和出口位置:
4)程序运行以后显示的迷宫:
5)得出结论:
(2)求解的迷宫没有通路的情况:
1)入口或出口位置指定不正确,即入口是通路,出口是障碍或入口障碍,出口通路;入口和出口都是障碍:
结果是:
2)入口和出口位置指定正确,即入口和出口都是通路:
结果是:
3)出口的位置超过迷宫的范围大小:
(3)程序运行的异常情况:
1)输入数据异常:
输入的行数或是列数不是整型的时候有以下情况:
a.程序按顺序执行了,但是程序不能正常结束。
b.出现应用程序报错处理。
输入的迷宫数据取值不是0或是1的时候:
a.迷宫数据都是整型,程序可以把大于的整型数据变为1输出。
b.迷宫的数据含有字符型数据时,当输入一个字符型数据后再也输不进去其它数,显示迷宫时剩余的位置由随机数填充。
c.迷宫数据含有浮点型数据时,浮点数所在行的数据可以输入完,如果还有下一行要输入数据的话就不能输入进去。
2)数据之间没有按照要求以空格隔开,只能输入一行的数据:
7结论
(1)总结:
这次的程序设计是迷宫的求解问题,由用户输入迷宫的行数和列数,并且指定入口和出口的坐标位置。
程序要能够以方阵形式输出迷宫,找到迷宫的所有路径并且把路径都输出,格式为(i,j,di)i,j是迷宫数组的横纵坐标,di表示方位,di的取值0到3,0表示向上,1表示向右,2表示向下,3表示向右。
程序存在的问题就是迷宫没有路径的判断问题,迷宫有路径就输所有路径,没有通路就没有结果显示,不能够输出“没有路径可走!
”的结果。
这样的处理不大合理,因为程序也可能在有路径的情况下出现异常导致没有结果输出。
对于这个问题的解决,可以先写一个函数判断有无路径,有路径就调用求解所有迷宫通路的函数,没有路径就输出“没有路径可走!
”的结果。
这样改进虽然显得有些繁琐了,不过最终还是可以把这个功能实现了。
对于这个修改的对策,我照着这样做以后,求解所有通路这个函数输出的路径的结果又出现了路径不对的问题。
两个函数我都分别测试了,没有什么问题,可是放一起后就出现了问题。
对于这样的结果我也弄不明白了。
(2)心得体会:
这次的程序设计虽然只是涉及了数据结构的栈的知识,题目应该不难,可是对于自己还是觉得比较困难,因为自己的基本功不到家。
迷宫这个问题如果用界面做的话应该会看着更加地简洁明了的,可是自己关于面向对象程序设计的知识实在是欠缺,因此没有这个能力做出来。
因此通过这次的程序设计让我看到了自己的很多的不足的地方,自己需要练好基本功,要深入地学习,不能够以应付的心态来学习。
致谢
首先需要感谢的是指导老师唐剑梅老师,在她的严格督促下才能按时完成这个课程设计,并且对于各种提出的问题很热情的解答,而且唐老师在百忙之中抽时间指导的精神实在难能可贵。
再者需要感谢的是交过我数据结构的周立章老师,没有他的教导自然就不可能有基础来完成课程设计了。
整个完成的过程中周围的同学给了不少帮助,而且帮忙解决了很多想不通的问题,在此真的非常感激每个人!
参考文献
[1]苏仕华等编著.数据结构课程设计.北京:
机械工业出版社,2007
[2]严蔚敏等编著.数据结构(C语言版).北京:
清华大学出版社,2003
[3]严蔚敏等编著.数据结构题集(C语言版).北京:
清华大学出版社,2003
附录
用户使用说明:
(1)程序运行以后,用户按照提示信息输入迷宫的行数和列数,数据之间以空格隔开。
输入完成以后敲回车键。
(2)按照提示信息输入二维迷宫数组的值,输入的值取值必须是整型数据,取值的大小可以不限定,大于0的数都会被处理为1。
其中0表示通路,1表示障碍。
(3)按提示信息输入入口和出口位置,注意要输入整型数据,还有就是入口和出口的位置都必须是通路才行。
输入完入口和出口的位置的数据后敲回车键。
(4)到此由用户输入的部分就完成了,程序显示加了围墙后的迷宫,以及有无通路的情况。
有通路就会输出所有的路径,没有通路就没有结果显示。