迷宫问题课程设计论文.docx
- 文档编号:30276255
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:21
- 大小:119.68KB
迷宫问题课程设计论文.docx
《迷宫问题课程设计论文.docx》由会员分享,可在线阅读,更多相关《迷宫问题课程设计论文.docx(21页珍藏版)》请在冰豆网上搜索。
迷宫问题课程设计论文
摘要
本课题主要研究在C语言的基础上用栈和队列两种放过实现求解迷宫,迷宫用一个二维数组来表示。
求解迷宫通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前进:
否则沿原路退回,换一个方向再继续探索;直至所有可能的通路都探索为止。
关键词:
迷宫;栈;队列;二维数组
1问题描述
设计一个简单迷宫程序,从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向;若所有方向均没有通路,则沿原点返回前一点,换下一个方向在继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。
并利用两种方法实现:
一种用栈实现,另一种用队列实现。
2需求分析
2.1课程设计目的
学生在教师指导下运用所学课程的知识来研究、解决一些具有一定综合性问题的专业课题。
通过课程设计(论文),提高学生综合运用所学知识来解决实际问题、使用文献资料、及进行科学实验或技术设计的初步能力,为毕业设计(论文)打基础。
2.2课程设计任务
(1)定义一个二维数组存放迷宫数据;
(2)画出查询模块的流程图;
(3)编写代码;
(4)程序分析与调试。
2.3设计环境
(1)WINDOWS2000/2003/XP/7/Vista系统
(2)VisualC++或TC集成开发环境
3概要设计
3.1数据结构设计
(1)迷宫类型
设迷宫为M行N列,利用maze[M][N]来表示一个迷宫,maze=0或1,其中0表示通路,1表示不通。
当从某点试探是,中间点有8个不同点可以试探,而四个角有3个方向,其他边缘点有5个方向,为使问题更容易分析我们用maze[M+2][N+2]来表示迷宫,而迷宫四周的值全部为1。
定义如下:
#defineM6/*迷宫的实际行*/
#defineN8/*迷宫的实际列*/
intmaze[M+2][N+2];
(2)队列的类型定义
队列的有关数据结构、试探方向等和栈的求解方法处理基本相同。
不同的是:
如何存储搜索路径。
在搜索过程中必须几下每一个可到达的坐标点,以便从这些点出发继续向四周搜索。
到达迷宫的出口点(m,n)后,为能够从出口沿搜索路径回溯直至入口,对于每一点,记下坐标点的同时,还要记下到达该点的前驱点,因此用一个结构体数组ele[MAX]作为队列的存储空间,因为每一点至少被访问一次,所以MAX至多等于m*n。
该结构体有三个域:
x、y和pre。
其中x、y分别为所到达点的坐标,pre为前驱点在elem中的下标。
除此之外,还需设定头、尾指针,分别指向队头,队尾。
类型定义如下:
typedefstruct//队的相关类型定义
{intx,y;
intpre;
}Elemtype;
typedefstruct//队列的类型定义
{Elemtypeelem[MAXSIZE];
intfront,rear;
intlen;
}SqQueue;
(3)队列的相关模块
定义函数DLmazepath(),利用队列实现迷宫求。
定义函数DLmazepath(),实现队列的迷宫路径输出。
定义函数InitQueue(),实现队列的初始化。
定义函数QueueEmpty(),判断队列是否为空,为空返回1,否则返回0.
定义函数GetHead(SqQueueq,Elemtype*e),实现队头元素的读取。
定义函数EnQueue(SqQueue*q,Elemtypee),实现入队操作。
定义函数DeQueue(SqQueue*q,Elemtype*e),实现出队操作。
定义函数Sprint(inta[M+2][N+2]),实现,迷宫的输出。
定义栈相关的函数见同伴的报告。
3.2系统流程图
(1)主函数
图3.1主函数流程图
(2)队列求解迷宫
图3.2队列求解迷宫流程图
4编码与实现
4.1分析
(1)主函数
voidmain()
{
inta,i,j,maze2[M+2][N+2];/*构造一个迷宫*/
intmaze[M+2][N+2]={
{1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,0,1,1,1,1},
{1,1,0,1,0,1,1,1,1,1},
{1,0,1,0,0,0,0,0,1,1},
{1,0,1,1,1,0,1,1,1,1},
{1,1,0,0,1,1,0,0,0,1},
{1,0,1,1,0,0,1,1,0,1},
{1,1,1,1,1,1,1,1,1,1}};
itemmove[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
/*坐标增量数组move的初始化*/
为使得程序更加人性化,更加友好,因此可将系统输出界面设置如下:
printf("|*****************迷宫求解系统*****************|\n");
printf("|1、栈方法求解迷宫的路径|\n");
printf("|2、队列求解的迷宫路径|\n");
printf("|3、退出系统|\n");
printf("|*******************************************|\n");
printf("\t\n\n请选择(0-3):
");scanf("%d",&a);
while(a!
=3)
{switch(a)
{Case1:
Sprint(maze);printf(“路径为:
\n");
Zmazepath(maze,move);break;
Case2:
Sprint(maze2);printf("路径:
\n");
DLmazepath(maze2,move);break;
default:
printf("\t\t选择错误!
!
\n");
}
printf("\t\n请选择(0-3).....\n");scanf("%d",&a);
}
printf("\n\t\t非常感谢您的使用!
\n");
}
(2)利用队列实现迷宫求解伪代码如下:
intDLmazepath_(intmaze[M+2][N+2],itemmove[8])
/*采用队列的迷宫算法。
Maze[M+2][N+2]表示迷宫数组,move[8]表示坐标增量数组*/
{
队的初始化;
将入口点坐标及到达该点的方向(设为-1)入队;
while(队不为空)
{for(从1到8个方向)
求新坐标点坐标,并将可到达点分别入队;
if(点(x,y)为出口点)结束输出路径,迷宫有路;
当前点搜索完8个方向后出队;
}returno/*迷宫五路*/
}
voidDLprintpath(SqQueueq)//输出迷宫路径,队列中保存的就是一条迷宫的通路
{inti;i=q.rear-1;
do
{printf("(%d,%d)<--",(q.elem[i]).x,(q.elem[i]).y);
i=(q.elem[i]).pre;
}
while(i!
=-1)
利用栈方法和队列方法用到的是同一个迷宫数组,
在使用栈方法实现迷宫求解时,为避免死循环改变了原来的迷宫数组的个别路径值,因此使用队列求解时不能得到相应的路径解,为避免此,我们可在用栈方法求解迷宫路径之前将数组赋值给另一个数组,这样队列求解迷宫时可以再原来不改变的迷宫数组下进行。
具体实现代码如下:
for(i=0;i for(j=0;j {maze2[i][j]=maze[i][j];} (3)队列的操作 voidInitQueue(SqQueue*q)/*队列的初始化*/ {将队中元素赋值为0;} intQueueEmpty(SqQueueq)/*判队空*/ {if(队长度为0)返回1; else返回0; } voidGetHead(SqQueueq,ElemType*e)/*读队头元素*/ {if(队的长度为0)输出提示队列为空; else将队中值赋给e; } voidEnQueue(SqQueue*q,ElemTypee)/*入队*/ { if(队列长度已满)输出提示; else { 将e中元素赋给队列; 队尾指针指向下一个元素;队长加1; } } voidDeQueue(SqQueue*q,ElemType*e)/*出队*/ { if(判队空)输出提示; else{将队中元素赋给e;队头指向下一个元素;队长减1;} } 4.2具体代码实现 #include #include #defineM6 #defineN8 #defineMAXSIZE100 #defineMAXM*N typedefstruct//栈的相关类型定义 { intx,y,d;//d下一步方向 }elemtype; typedefstruct { elemtypedata[MAXSIZE]; inttop; }Sqstack; typedefstruct { intx,y; }item; typedefstruct//队的相关类型定义 { intx,y; intpre; }Elemtype; typedefstruct//队列的类型定义 { Elemtypeelem[MAXSIZE]; intfront,rear; intlen; }SqQueue; /*栈函数*/ voidInitStack(Sqstack*s)//构造空栈 { s->top=-1; } intStackempty(Sqstacks)//判断栈是否为空 { if(s.top==-1)return1; elseeturn0; } voidpush(Sqstack*s,elemtypee)//入栈 { if(s->top==MAXSIZE-1) {printf("Stackisfull\n"); return; } s->top++; s->data[s->top].x=e.x; s->data[s->top].y=e.y; s->data[s->top].d=e.d; } voidpop(Sqstack*s,elemtype*e)//出栈算法 { if(s->top==-1) { printf("Stackisempty\n"); return; } e->x=s->data[s->top].x; e->y=s->data[s->top].y; e->d=s->data[s->top].d; s->top--; } /*队函数*/ voidInitQueue(SqQueue*q)//队的初始化 { q->front=q->rear=0; q->len=0; } intQueueEmpty(SqQueueq)//判断队空 { if(q.len==0) return1; elsereturn0; } voidGetHead(SqQueueq,Elemtype*e)//读队头元素 { if(q.len==0) printf("Queueisempty\n"); else *e=q.elem[q.front]; } voidEnQueue(SqQueue*q,Elemtypee)//入队 { if(q->len==MAXSIZE) printf("Queueisfull\n"); else { q->elem[q->rear].x=e.x;q->elem[q->rear].y=e.y; q->elem[q->rear].pre=e.pre;q->rear=q->rear+1; q->len++; } } voidDeQueue(SqQueue*q,Elemtype*e)//出队 { if(q->len==0) printf("Queueisempty\n"); else { e->x=q->elem[q->rear].x;e->y=q->elem[q->rear].y; e->pre=q->elem[q->rear].pre;q->front=q->front+1; q->len--; } } voidSprint(inta[M+2][N+2]) { inti,j; printf("迷宫为: \n"); for(i=0;i { for(j=0;j printf("%2d",a[i][j]); printf("\n"); } } voidZprintpath(Sqstacks) {//输出迷宫路径,栈中保存的就是一条迷宫的通路 elemtypetemp; printf("(%d,%d)<--",M,N); while(! Stackempty(s)) { pop(&s,&temp); printf("(%d,%d)<--",temp.x,temp.y); } printf("\n"); } voidZmazepath(intmaze[M+2][N+2],itemmove[8]) {//栈的迷宫求解输出 Sqstacks; elemtypetemp;intx,y,d,i,j; InitStack(&s);//栈的初始化 temp.x=1;temp.y=1;temp.d=-1; push(&s,temp); while(! Stackempty(s)) { pop(&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; push(&s,temp); x=i;y=j; maze[x][y]=-1; if(x==M&&y==N) { Zprintpath(s); return; } elsed=0; }//if elsed++; }//while }//while return; printf("迷宫无路\n");return; } voidDLprintpath(SqQueueq) {//输出迷宫路径,队列中保存的就是一条迷宫的通路 inti; i=q.rear-1; do { printf("(%d,%d)<--",(q.elem[i]).x,(q.elem[i]).y); i=(q.elem[i]).pre; }while(i! =-1); printf("\n"); } voidDLmazepath(intmaze1[M+2][N+2],itemmove[8]) {//队列的迷宫求解 SqQueueq; Elemtypehead,e; intx,y,v,i,j; InitQueue(&q);//队列的初始化 e.x=1;e.y=1;e.pre=-1; EnQueue(&q,e); maze1[1][1]=-1; while(! QueueEmpty(q)) {GetHead(q,&head); x=head.x;y=head.y; for(v=0;v<8;v++) {i=x+move[v].x; j=y+move[v].y; if(maze1[i][j]==0) {e.x=i;e.y=j;e.pre=q.front; EnQueue(&q,e); maze1[x][y]=-1; }//if if(i==M&&j==N) {DLprintpath(q); return; } }//for DeQueue(&q,&head); }//while printf("迷宫无路! \n"); return; } voidmain() {inta,i,j,maze2[M+2][N+2]; intmaze[M+2][N+2]={ {1,1,1,1,1,1,1,1,1,1}, {1,0,1,1,1,0,1,1,1,1}, {1,1,0,1,0,1,1,1,1,1}, {1,0,1,0,0,0,0,0,1,1}, {1,0,1,1,1,0,1,1,1,1}, {1,1,0,0,1,1,0,0,0,1}, {1,0,1,1,0,0,1,1,0,1}, {1,1,1,1,1,1,1,1,1,1}};/*构造一个迷宫*/ itemmove[8]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}}; /*坐标增量数组move的初始化*/ for(i=0;i for(j=0;j {maze2[i][j]=maze[i][j];} printf("|******************迷宫求解系统******************|\n"); printf("||\n"); printf("|1、栈求解迷宫的路径|\n"); printf("||\n"); printf("|2、队列求解的迷宫路径|\n"); printf("||\n"); printf("|3、退出系统|\n"); printf("||\n"); printf("|**********************************************|\n"); printf("\t\n\n请选择(0-3): ");scanf("%d",&a); while(a! =3) { switch(a) { case1: Sprint(maze);printf("求解路径为: \n"); Zmazepath(maze,move);break; case2: printf("求解路径为: \n"); DLmazepath(maze2,move);break; default: printf("\t\t选择错误! ! \n"); } printf("\t\n请选择(0-3): ");scanf("%d",&a); } printf("\n\t\t结束退出程序! \n"); } 5测试分析 测试数据及结果如下: (1)系统友好界面输出 图5.1进入系统界面运行结果 (2)选择1,运行结果输出如下: 图5.2迷宫以及使用栈求解迷宫路径的输出 (3)选择2、3运行结果如下: 图5.3迷宫以及使用队列求解迷宫路径的输出 (4)选择3运行结果如下: 图5.3退出程序 根据结果分析: 利用栈求得的路径不一定是最短路径,而用队列求得的路径是最短路径。 6课程设计总结 课程设计终于在本组组员共同的努力下完成了。 通过本次课程设计让我对栈和队列这一章的知识有了进一步了解,也让我知道了用栈和队列实现迷宫问题的基本原理,知道了栈和队列的不同存储结构的定义和算法描述,同时也学会了编写简单的迷宫问题的程序。 选了题目之后,我感觉题目之前已经做过一点相关的实验,本以为很快就能搞好, 但是,真正做起来才感觉没有那么简单,让我更加意识到自己的不足,我所知道的,所懂的太少了。 在刚开始编程的时候,我感到有点迷茫,虽然懂得了其相应的算法和思想,但是却不知道要怎样安排程序的结构、以及什么方法将其功能实现,更不知道要从哪里开始着手进行。 老师说的没错,我们平时的学习中程序练习太少,写的太少,什么事不可能一蹴而就,都是通过一点一滴的锻炼慢慢积累起来的。 所以我觉得在以后的学习中,我会更加注重实践,注重多练,多积累,为自己的以后工作打下结实的基础。 参考文献 [1]黄同成,黄俊民,董建寅.数据结构[M].北京: 中国电力出版社,2008 [2]董建寅,黄俊民,黄同成.数据结构实验指导与题解[M].北京: 中国电力出版社,2008 [3]严蔚敏,吴伟民.数据结构(C语言版)[M].北京: 清华大学出版社,2002 [4]刘振鹏,张晓莉,郝杰.数据结构[M].北京: 中国铁道出版社,2003 致谢 在这次课程设计的撰写过程中,我得到了许多人的鼓励和帮助,在此,我表示衷心的感谢。 首先,我要感谢我的指导老师黄同城老师,他在课程设计上给予我的很大的帮助,指导课程设计的具体实现方向。 并且为我分析部分比较难懂的地方,让我把此次课程设计做得更加完善。 在此期间,我对迷宫问题有了更深刻的认识,而且也明白了很多做课程设计需要注意的地方,让我变得更严谨。 然后,我要感谢我们第一大组组员们,在组内讨论时,他们各抒己见,思路发散,讨论时锱铢必较,正是因为这份热情,我们对这次的课程设计充满了激情,方向也很明确。 在汇报进程的时候,组内积极讨论,相互竞争,优缺互补,让我们的课程设计更加完美,让我们自己在讨论中知道自己的优点,认识自己的缺点,不断完善自己。 最后,再次感谢一路上帮助过我的老师同学,没有你们的帮助,我无法完成这次任务,谢谢你们。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 迷宫 问题 课程设计 论文