迷宫最短路径.docx
《迷宫最短路径.docx》由会员分享,可在线阅读,更多相关《迷宫最短路径.docx(40页珍藏版)》请在冰豆网上搜索。
迷宫最短路径
湖南工业大学
课程设计
计算机与通信学院(系、部)2012~2013学年第2学期
课程名称数据结构课程设计指导教师xxxx职称副教授
学生姓名xxx专业班级计算机科学与技术学号xxxxxx
题目迷宫最短路径求法
成绩起止日期2013年6月26日~2013年6月27日
目录清单
序号
材料名称
资料数量
备注
1
课程设计任务书
1
2
课程设计说明书
1
3
张
4
5
6
湖南工业大学
课程设计任务书
2012—2013学年第2学期
计算机与通信学院(系、部)计算机科学与技术专业1203班级
课程名称:
数据结构课程设计
设计题目:
求迷宫问题的最短路径
完成期限:
自2013年6月25日至2013年6月27日共周
内
容
及
任
务
一:
设计的主要技术参数
1、函数的调用
2、公用体、结构体
3、循环语句和选择语句
4、队列
5、指针与数组的应用
6、结构体的应用
7:
遍历
三、设计工作量
1、函数编码设计
2、函数的调试及运行
3、系统的调试一、设计内容:
迷宫问题是实验心理学中的一个经典问题,心理学家把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。
迷宫中设置很多隔壁,对前进方向形成了多处障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以达到出口。
我们要解决的是如何找到一条迷宫的最短路径。
二、任务:
掌握结构化程序设计的主体思想,以自顶向下逐步求精的方法编制程序解决一些实际的问题,为将来编写软件积累一些典型的案例处理经验。
1.设计正确,方案合理。
2.界面友好,使用方便。
3.程序精炼,结构清晰。
4.设计报告,含程序设计说明,用户使用说明,源程序清单及程序框图。
5.上机演示。
6.按学号顺序选课题号,并在规定的时间内独自完成相关课题的C源程序编写、调整和运行。
源程序及编译生成各文件均保存在软盘中;
7.按本任务书的要求,按附录的要求编写《课程设计报告》(Word文档格式)。
并用A4的复印纸打印并装订。
进
度
安
排
起止日期
工作内容
2013.06.25~2013.06.27
选题及组内成员分任务,开始熟悉课题并进行构思
2013.06.25
编写源程序、运行、修改
2013.06.26
编写文档并打印文稿
主
要
参
考
资
料
[1]谭浩强.C语言程序设计(第三版)[M].北京:
清华大学出版社,2005
[2]数据结构实验教程[M].北京:
高等教育出版社,2005
[3]刘振鹏罗文劼石强.数据结构(第三版)中国铁道出版社
指导教师(签字):
年月日
系(教研室)主任(签字):
年月日
数据结构课程设计
设计说明书
求迷宫的最短路径
起止日期:
2013年6月25日至2013年6月27日
学生姓名
xxx
班级
计算机科学与技术1203
学号
xxxx
成绩
指导教师(签字)
计算机与通信学院(部)
2013年6月26日
1课程设计简介
1.1课程设计的目的
通过实验,掌握如下内容:
1:
进一步掌握指针、模板类、异常处理的使用;
2:
掌握队列的操作和实现方法;
3:
学习使用队列解决实际问题的能力;
4:
学习使用图的广度优先搜索解决实际问题的能力。
1.2课程设计内容
2
利用数据结构的队列遍历求出迷宫问题的最短路径。
迷宫求解问题如下:
迷宫问题是实验心理学中的一个经典问题,心理学家把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。
迷宫中设置很多隔壁,对前进方向形成了多处障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以达到出口。
我们要解决的是如何找到一条迷宫的最短路径。
测试算法的迷宫由使用者设置,例如设置的迷宫如下图所示
1.3程序功能
打印老鼠走出迷宫的最短路径
2.程序算法及功能分析
2.1存储结构:
队列顺序存储
示意图如下:
2.2关键算法分析
核心算法思想:
1:
如果采用直接递归的方式,用栈很容易实现路径的输出,但是这条路径不一定是最短路径,为了改变算法,达到输出最短路径的目的,采用队列的实现方式。
2:
为查找最短路径,使用了图中的广度搜索。
算法的基本思路为:
从迷宫入口点(1,1)出发,向四周搜索,几下所有一步能到达的坐标点;然后依次再从这些点出发,再几下所有一步能到达的坐标点;依此类推,直到到达迷宫的出口点(m,n)为止,然后从出口点沿着搜索路径回溯到入口。
typedefstruct
{
intx,y;//行、列坐标
intpre;//链域
}sqtype;
sqtypesq[r];//作为队列的存储空间,记录被访问过的点
关键算法思想的描述和实现:
为寻求最短路径,采用广度优先搜索方法,使用队列实现路径存储,队列中每个元素用结构存储体系,包含迷宫坐标,队列中的序号,队首指针front,队尾指针rear,最后采用回溯的方法将路径打印出来。
算法1:
intSHORTPATH(intmaze[m2][n2])//找迷宫maze的最短路径
{
inti,j,v,front,rear,x,y;
sq[1].x=1;//设定入口的行坐标
sq[1].y=1;//设定入口的纵坐标
sq[1].pre=0;
front=1;//进入迷宫时的队首指针
rear=1;//进入迷宫时的队尾指针
maze[1][1]=-1;//标记入口点已经到达
算法2:
遍历每个位置的四周,将没有走过的位置入队,形成树形的队列,通过出队操作就能找出最短路径
{
x=sq[front].x;y=sq[front].y;//(x,y)为出发点
for(v=0;v<8;v++)//搜索(x,y)的8个相邻点(i,j)是否可到达
{
i=x+move[v].x;
j=y+move[v].y;
if(maze[i][j]==0)//(i,j)为可到达点,将其入队
{
rear++;
sq[rear].x=i;sq[rear].y=j;
sq[rear].pre=front;
maze[i][j]=-1;//标记(i,j)已到达过的点
}
算法3:
广度优先搜索算法的实现,找到最短路径。
广度优先算法在此相当于树的层次遍历,如下图:
在迷宫地图中,关键算法三通过不断调用算法二就能将地图中可以走的位置入队,形成类似上图的树形结构,之后广度搜索到的最浅深度即为最短路径。
if(maze[i][j]==0)//(i,j)为可到达点,将其入队
{
rear++;
sq[rear].x=i;sq[rear].y=j;
sq[rear].pre=front;
maze[i][j]=-1;//标记(i,j)已到达过的点
}
if((i==m)&&(j==n))//到达出口
{
PRINTPATH(sq,rear);//打印路径
//RESTORE(maze);//恢复迷宫
return1;//成功,返回1
}
算法4:
使用队列指针查找队首指针的方式,从队尾回溯到队首,标记出最短路径。
队列的元素示意如图:
intSHORTPATH(intmaze[m2][n2])//找迷宫maze的最短路径
{
inti,j,v,front,rear,x,y;
sq[1].x=1;
sq[1].y=1;
sq[1].pre=0;
front=1;
rear=1;
maze[1][1]=-1;//标记入口点已经到达
while(front<=rear)//队列非空
{
x=sq[front].x;y=sq[front].y;//(x,y)为出发点
for(v=0;v<8;v++)//搜索(x,y)的8个相邻点(i,j)是否可到达
{
i=x+move[v].x;
j=y+move[v].y;
if(maze[i][j]==0)//(i,j)为可到达点,将其入队
{
rear++;
sq[rear].x=i;sq[rear].y=j;
sq[rear].pre=front;
maze[i][j]=-1;//标记(i,j)已到达过的点
}
if((i==m)&&(j==n))//到达出口
{
PRINTPATH(sq,rear);//打印路径
//RESTORE(maze);//恢复迷宫
return1;//成功,返回1
}
}
front++;//出队,front指向新的出发点
}//队空循环结束
return0;//迷宫无路径,返回0
}
时间复杂度和空间复杂度
算法一盒二的时间复杂度与空间复杂度均为O
(1)。
算法三占用空间为迷宫边长n的平方,故空间复杂度为O(n*n).最多走n*n步,最少走1步,故时间复杂度为O(n*n/2)。
1用代码创建3个文件夹,用于存放数据
。
main(){
if((fp=fopen("c:
\\book.txt","rb+"))==NULL){
printf("在c盘根目录下没有找到储存图书信息的book.txt文件\n请选择1--手动导入!
2--创建此文件\n");
scanf("%d",&xuan);
switch(xuan){
case2:
if((fp=fopen("c:
\\book.txt","wb+"))!
=NULL)
printf("创建成功\n\n");
break;
case1:
printf("请把名为book.txt的文件复制到c盘根目录下\n\n");
}
}
if((fpj=fopen("c:
\\jieyue.txt","rb+"))==NULL){
printf("在c盘根目录下没有找到储存借阅信息的jieyue.txt文件\n请选择1--手动导入!
2--创建此文件\n");
scanf("%d",&xuan);
switch(xuan){
case2:
if((fpj=fopen("c:
\\jieyue.txt","wb+"))!
=NULL)
printf("创建成功\n\n");
break;
case1:
printf("请把名为jieyue.txt的文件复制到c盘根目录下\n\n");
}
}
if((fps=fopen("c:
\\student.txt","rb+"))==NULL){
printf("在c盘根目录下没有找到储存学生信息的student.txt文件\n请选择1--手动导入!
2--创建此文件\n");
scanf("%d",&xuan);
switch(xuan){
case2:
if((fps=fopen("c:
\\student.txt","wb+"))!
=NULL)
printf("创建成功\n\n");
break;
case1:
printf("请把名为student.txt的文件复制到c盘根目录下\n\n");
}
}
2,。
进入界面
voidmenu()//菜单
{system("cls");
printf("\n\n");
printf("*************欢迎进入图书管理查询系统********\n");
for(i=0;i<80;i++)
printf("#");
printf("\n");
printf("\t\t1-----图书录入\t\t\t");
printf("2-----图书浏览\n\n");
printf("\t\t3-----图书查询\t\t\t");
printf("4-----修改删除图书\n\n");
printf("\t\t5-----借阅图书\t\t\t");
printf("6-----归还图书\n\n");
printf("\t\t7-----借阅查询\t\t\t\n");
printf("\n\t\t\t\t输入其他任意键退出\n");
printf("\n");
for(i=0;i<80;i++)
printf("#");
printf("\n\n");
}
2录入图书,输入图书的8种信息,图书名,图书编号,图书作者,出版日期,价格,出版社,类别,入库,成功后返回主菜单。
voidend()//录入图书
{system("cls");
boboo,booq;
printf("请输入图书名(最多十个字符):
");
scanf("%s",boo.name);
do{
i=1;
printf("请输入图书编号(最多十个字符):
");
scanf("%s",boo.num);
fread(&booq,sizeof(bo),1,fp);
while(!
feof(fp)){
if(strcmp(booq.num,boo.num)==0){
printf("\n该编号已存在请重新输入\n\n");
i=0;
break;
}
fread(&booq,sizeof(bo),1,fp);
}
rewind(fp);
}while(i==0);
printf("请输入图书作者(最多十个字符):
");
scanf("%s",boo.writer);
printf("请输入图书出版日期(例如2001年5月3日出版则输入20010503):
");
scanf("%d",&boo.date);
printf("请输入图书价格:
");
scanf("%f",&boo.price);
printf("请输入图书出版社(最多十个字符):
");
scanf("%s",boo.press);
printf("请输入图书类别(最多十个字符):
");
scanf("%s",boo.leibie);
printf("请输入图书入库数:
");
scanf("%d",&boo.kucun);
boo.jiechu=0;
getchar();
fseek(fp,0,2);
fwrite(&boo,sizeof(bo),1,fp);
printf("\n录入成功!
回到主菜单");
system("pause");
}
9其他键自动退出
学了一个学期的C语言,功底还不扎实,再说C语言学的也并不好,刚做课程实际时,觉得自己肯定无法完成这项工作的,但经过慢慢的尝试探索,不断的发现错误改正错误,还是将其完成了,虽然并不完美
近一个礼拜中,我们有过山穷水尽的困惑;有过柳暗花明的惊喜;有过唇枪舌剑的辩论;有过相互鼓励的安慰。
一个多礼拜的时间我们经历了很多,也收获了很多。
与其说它是体力与脑力的作业,不如说它是合作精神和毅力的考验。
经过这次课程设计,我学到了很多知识和技能,并学会了用所学的知识解决实际问题。
同过本次的课程设计,巩固了我的C语言知识,发现了自身的诸多不足之处,总之,这是一次很好的锻炼机会
参考文献
[4]谭浩强.C语言程序设计(第三版)[M].北京:
清华大学出版社,2005
[5]廖雷、罗代忠.C语言程序设计基础实验教程[M].北京:
高等教育出版社,2005
[6]谭浩强.C程序设计解题与上机指导(第三版)[M].北京:
清华大学出版社,2005
[7]廖雷等.C语言程序设计基础[M].北京:
高等教育出版社,2004
[8]谭浩强,张基温,唐永炎.C语言程序设计教程. 北京:
高等教育出版社,2003
附源代码
#include
#include
#include
FILE*fp,*fpj,*fps;
inti,xuan;
typedefstructbook{
charname[10];
charnum[10];
charwriter[10];
intdate;
charpress[10];
floatprice;
charleibie[10];
intkucun;
intjiechu;
}bo;
typedefstructstudent{
charname[10];
charnum[10];
intjie;
}st;
typedefstructjieyue{
charsnum[10];
charbnum[10];
}ji;
voidmenu()//菜单
{system("cls");
printf("\n\n");
printf("*************欢迎进入图书管理查询系统********\n");
for(i=0;i<80;i++)
printf("#");
printf("\n");
printf("\t\t1-----图书录入\t\t\t");
printf("2-----图书浏览\n\n");
printf("\t\t3-----图书查询\t\t\t");
printf("4-----修改删除图书\n\n");
printf("\t\t5-----借阅图书\t\t\t");
printf("6-----归还图书\n\n");
printf("\t\t7-----借阅查询\t\t\t\n");
printf("\n\t\t\t\t输入其他任意键退出\n");
printf("\n");
for(i=0;i<80;i++)
printf("#");
printf("\n\n");
}
voidend()//录入图书
{system("cls");
boboo,booq;
printf("请输入图书名(最多十个字符):
");
scanf("%s",boo.name);
do{
i=1;
printf("请输入图书编号(最多十个字符):
");
scanf("%s",boo.num);
fread(&booq,sizeof(bo),1,fp);
while(!
feof(fp)){
if(strcmp(booq.num,boo.num)==0){
printf("\n该编号已存在请重新输入\n\n");
i=0;
break;
}
fread(&booq,sizeof(bo),1,fp);
}
rewind(fp);
}while(i==0);
printf("请输入图书作者(最多十个字符):
");
scanf("%s",boo.writer);
printf("请输入图书出版日期(例如2001年5月3日出版则输入20010503):
");
scanf("%d",&boo.date);
printf("请输入图书价格:
");
scanf("%f",&boo.price);
printf("请输入图书出版社(最多十个字符):
");
scanf("%s",boo.press);
printf("请输入图书类别(最多十个字符):
");
scanf("%s",boo.leibie);
printf("请输入图书入库数:
");
scanf("%d",&boo.kucun);
boo.jiechu=0;
getchar();
fseek(fp,0,2);
fwrite(&boo,sizeof(bo),1,fp);
printf("\n录入成功!
回到主菜单");
system("pause");
}
voidprint()//浏览图书
{system("cls");
boboo;
printf("书名编号作者价格出版社类别原始库存借出\n");
fread(&boo,sizeof(bo),1,fp);
while(feof(fp)==0){
printf("%-10s%-10s%-10s%-10.2f%-10s%-10s%-10d%-4d\n",boo.name,boo.num,boo.writer,boo.price,boo.press,boo.leibie,boo.kucun,boo.jiechu);
fread(&boo,sizeof(bo),1,fp);
}
printf("\n浏览图书完毕!
回到主菜单");
system("pause");
}
intdui(char*p,char*p1)//对比两个字符串的相关度(用于精确搜索)
{
intbao=0,fan=1;
for(i=0;i<(int)strlen(p1);i++){
if(p[0]==p1[i]){
bao=i;
break;
}
}
if((int)strlen(p)>(int)strlen(p1)-bao+1)
return0;
else
for(i=0;i<(int)strlen(p);i++){
if(p[i]!
=p1[bao+i])
fan=0;
}
returnfan;
}
voidfind()//查询图书
{system("cls");
charhao[10];
intfan=1;
intbian=1;
boboo;
printf("请选择查询类型:
\n\n\t\t1-按图书编号模糊查询2-按图书名关键字查询\n");
printf("\n\t\t3-按图书编号精确查询4-按图书名精确查询\n\n代码:
");
scanf("%d",&xuan);
if(xuan==1){
printf("请输入编号(最多十个字符):
");
scanf("%s",hao);
printf("序号书名编号作者价格出版社类别原始库存借出\n");
fread(&boo,sizeof(bo),1,fp);
while(!
feof(fp)){
fan=dui(hao,boo.num);
if(fan==1){
printf("%-5d%-10s%-10s%-