迷宫问题课程设计报告文档格式.docx
- 文档编号:18617849
- 上传时间:2022-12-29
- 格式:DOCX
- 页数:20
- 大小:113.98KB
迷宫问题课程设计报告文档格式.docx
《迷宫问题课程设计报告文档格式.docx》由会员分享,可在线阅读,更多相关《迷宫问题课程设计报告文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
由于其只有一个非障碍位置,所以接下来移动到(0,1)(序列号1),其前节点序列号为0,防止稍后的搜索再经过这个位置。
从(0,1)移动到(1,1)(序列号2),放入队列中,其前节点序列号为1,(1,1)存在(1,2)(序列号3)、(2,1)(序列号4)两个可移动位置,其前序列号均为2。
标记已被搜索过,对于每一个非障碍位置,它的相邻非障碍节点均入队列,实现了广度优先遍历算法,且它们的前序列号均为该位置的序列号。
所以如果存在路径,则从出口处节点的位置,逆序则可以找到其从出口到入口的通路。
实现了查找最短路径。
(如表格1所示为所建队列)
将(0,0)入队列
判断首节点是否为通路
路
判断队列否为空
左边
是否存在通路
下边是否存在通路
右边是否存在通路
上边是否存在通路
是否到达迷宫出口处
将队头出队
存储节点,将节点入队列
迷宫路由算法流程图:
N循环结束
无解迷宫
Y
N
N
有解迷宫
循环结束
图1迷宫路由算法流程图
表1图示队列表
012345678910
(0,0)
(0,1)
(1,1)
(1,2)
(2,1)
(2,2)
(1,3)
(2,3)
(0,3)
(3,3)
(3,4)
-1
1
2
3
4
5
6
7
9
由此可看出,从(3,4)->
(3,3)->
(2,3)->
(2,2)->
(1,2)->
(1,1)->
(0,1)->
(0,0)得到最短路径。
1、数据输入形式和输入值的范围:
生成迷宫时须输入迷宫的行数和列数,其最大值均不应超过50;
手动输入迷宫矩阵时以0表示无障碍为通路,1表示该点有障碍为墙。
所有输入中,元素的值均为整数。
2、结果的输出形式:
所有进入界面中,只有当输入正确(如密码正确或输入值在可操作范围内)时才可进入下一界面,否则均不可进入下一届面操作,当完成迷宫生成后,进入迷宫路由查找算法,输出查找的每次循环过程,及最终查找结果:
如找到,则显示路径(表述);
否则显示为查找到。
显示迷宫生成图形(如有路径则同样显示路径结果)。
3、测试数据:
a、在输入密码中输入13,输入1234
b、在输入行、列数中:
输入5、56,输入5、5
c、在输入选择自动生成或手动生成中,选择相应操作,查看结果
d、选择输入3,重新输入矩阵的行列数。
e、选择是否循环执行此程序。
(-1表示输入结束)
三、概要设计
1、为了实现上述功能,需要:
①构造一个二维数组maze[M+2][N+2]用于存储迷宫矩阵;
②自动或手动生成迷宫,即为二维数组maze[M+2][N+2]赋值;
③将构造一个队列用于存储迷宫路由;
④建立迷宫节点structpoint,用于存储迷宫中每个节点的访问情况。
⑤实现迷宫路由算法,用广度优先遍历实现查找迷宫最短路径。
如找到路径则显示路径,否则显示为查找到。
同时显示生成迷宫。
⑥在屏幕上显示操作菜单。
2、本程序包含12个函数:
(1)主函数main()
(2)手动生成迷宫函数shoudong_maze()
(3)自动生成迷宫函数zidong_maze()
(4)打印每次显示结果print_maze()
(5)显示生成迷宫bulid_maze()
(6)显示迷宫生成图形(如有路径生成,则显示路径)result_maze()
(7)入队操作enqueue()
(8)出队操作dequeue()
(9)判断队列是否为空is_empty()
(10)访问节点visit()
(11)寻找迷宫路由(求解迷宫中最短路径)mgpath()
(12)菜单操作menu()
各函数之间的关系如下图(图1)所示:
函数关系图:
shoudong_maze
idong_maze
build_maze
mainmenuenqueue
dequeue
mgpathis_empty
visit
print_maze
result_maze
图2各函数间关系图
四、详细设计
实现概要设计中定义的所有数据类型,对各个操作给出伪代码算法。
对于主程序和各个模块也给出相应的伪代码算法。
1、节点类型和指针类型
迷宫矩阵类型:
intmaze[M+2][N+2];
为方便操作使得其为全局变量
迷宫中节点类型及队列类型:
structpoint{introw,col;
intpredecessor;
}queue[512];
2、迷宫的操作
(1)手动生成迷宫
voidshoudong_maze(intm,intn)
{定义变量i,j;
m为迷宫中行数,n为迷宫中列数
利用for循环控制循环
以i,j控制迷宫中行列数的循环输入
以0表示通路,以1表示障碍,给maze[i][j]赋值。
循环结束,完成迷宫生成}
(2)自动生成迷宫
voidzidong_maze(intm,intn)
以i,j控制迷宫中行列数的循环赋值操作
以0表示通路,以1表示障碍
用0+(int)(2*rand()/(RAND_MAX+1.0))随机获得0、1,给maze[i][j]赋值,循环结束,完成迷宫生成}
(3)生成迷宫打印
voidprint_maze(intm,intn)
{此函数主要用于将迷宫路由算法中每次操作结果显示出来
定义变量,用for控制循环
以i,j控制迷宫中行列数的循环操作,将maze[i][j]显示出来}
(4)出示时显示迷宫生成结果
voidbuild_maze(intm,intn)
{首先进行清屏,打出屏幕提示信息,显示迷宫入口和出口,调用函数print_maze()}
(5)迷宫生成图形的显示操作
voidresult_maze(intm,intn)
{定义整型变量i,j;
用i,j控制迷宫行列数的循环操作,显示迷宫图形。
在循环中,如果迷宫中为通路,(即maze[i][j]=0或2)则显示“”;
如果迷宫中为障碍(maze[i][j]=1),则显示“■”,如果有最短路径(maze[i][j]=3)则显示“□”。
}
(6)迷宫求解路由求解操作
①迷宫中队列入队操作
voidenqueue(structpointp)
{将p放入队尾tail,将tail加1}
②迷宫中队列出队操作
structpointdequeue()
{head加1;
返回queue的队头[head-1]}
③判断队列是否为空
intis_empty()
{返回head==tail值,即当队列为空时,返回0值;
④访问矩阵中某一个节点
voidvisit(introw,intcol,intmaze[52][52])
{建立新的队列节点visit_point,将其中的值分别赋为row,col,head-1;
head-1表示前一个可以走的通路的位置。
将maze[row][col]=2,表示该节点已被访问过;
调用enqueue(visit_point);
将该节点入队列;
⑤迷宫求解路径算法实现函数
intmgpath(intmaze[52][52],intm,intn)
{首先定义迷宫入口处节点structpointp={0,0,-1},入口为最左上角,从maze[0][0]开始访问。
如果入口处即为障碍,则此迷宫无解,返回0值;
程序结束。
否则访问入口处节点,将入口处节点标记为访问过maze[p.row][p.col]=2,调用函数enqueue(p)将该节点入队列。
判断队列是否为空,如果不为空,则运行底下的操作:
{调用dequeue()函数,将队头元素返回给p,
如果p.row=m-1同时p.col=n-1即访问到迷宫出口处,即所有通路处全部被访问过,且找到了路径,则程序结束。
如果p.col+1<
n同时maze[p.row][p.col+1]=0即未访问到超过迷宫范围的节点,同时节点p的右边有通路,则调用visit(p.row,p.col+1,maze);
访问该位置,新建节点存储该位置(其p.predecessor所存储的为前一个可以被访问的可通过的通路节点的位置)并将该节点入队列,标志该节点已被访问过。
m同时maze[p.row+1][p.col]=0即未访问到超过迷宫范围的节点,同时节点p的下边有通路,则调用visit(p.row,p.col+1,maze);
如果p.col-1>
0同时maze[p.row][p.col-1]=0即访问未超过迷宫范围p的左边存在节点,同时该节点为通路,则调用visit(p.row,p.col-1,maze);
如果p.row-1>
0同时maze[p.row][p.col-1]=0即访问未超过迷宫范围p的上边存在节点,同时该节点为通路,则调用visit(p.row-1,p.col,maze);
调用函数print_maze,打印出关于p节点周围的横纵坐标的访问情况。
在未访问到无通路,或者未访问到出口处时,循环执行以上程序。
如果最后p.row=m-1同时p.col=n-1,访问到出口处,即找到从迷宫入口处到出口处的路径时,将迷宫路径打印出来:
{首先打印出出口节点,标记其为最短路径的通路标志,maze[p.row][p.col]=3如果p.predecessor不等于-1,则继续打印,p=queue[p.predecessor]打印该节点,标记节点为最短路径通路}
否则显示此迷宫无解。
返回0。
3、菜单操作
voidmenu()
{定义整型变量m,n,用于控制管理迷宫的行数和列数
定义整型变量cycle,用于控制循环,是否重复运行此程序。
定义整型变量secret_code,进入本操作界面的密码。
定义整型变量choice,用于控制选择菜单。
显示欢迎界面,输入用户密码,如果密码不正确,则显示“密码错误,请重新输入”,重新输入,只有当输入密码正确时,才进入操作界面。
清屏处理,进入操作界面。
输入迷宫的行数、列数,迷宫的行列数均不得超过50,否则显示“行列数超出预设范围,请重新输入”重新输入行、列数。
当输入行列数符合要求时,进入操作菜单栏
1------------------------------手动生成迷宫
2------------------------------自动生成迷宫
3------------------------------迷宫行列数输入有误,选择重新输入
输入选择(choice)
使用switch语句根据choice选择,以下操作
case1(如果选择的是1):
执行手动生成迷宫函数shoudong_maze(m,n);
调用build_maze(m,n)显示出生成的迷宫,及其入口和出口,break。
case2(如果选择的是2):
执行自动生成迷宫函数zidong_maze(m,n);
调用build_maze(m,n)显示出生成的迷宫,及其入口和出口,break。
case3(如果选择的是3):
首先进行清屏,重新输入迷宫的行列数且同样必须在可操作范围内。
否则循环此操作,重新输入行列数。
}
调用
mgpath(maze,m,n),寻找迷宫路由(即迷宫路径)
调用result_maze(m,n),显示出迷宫图形及路径
选择是否重新输入迷宫,如果不继续,-1退出。
4、主函数
voidmain()
{system(“colorf0”);
//设置屏幕及字体颜色
调用菜单函数menu();
}
五、调试分析
在调试过程中,首先使用的是栈进行存储,但是由此产生了,寻找到路径,但是此路径并不一定就是最短路径,所以通过比较算法,改使用广度优先遍历可以查找到最短路径。
由此可以得出使用栈不利于实现这一算法,因此改使用队列存储,查找最短路径。
在实现这一算法过程,注意将访问过的节点进行标记,且注意障碍的不同设置方式对此操作的不同影响。
同时注意队列中存储的是非障碍节点,但是由于广度遍历的算法,使得从出口到入口处所有节点彼此相关。
则在调用时注意区别。
六、使用说明
程序名为maze.exe,运行环境为DOS,程序执行后显示:
——————欢迎进入用户界面————————
请输入用户密码
(注:
密码为1234,方可进入用户界面,否则不可进入。
)
输入1234,显示密码正确。
请输入行数:
请输入列数:
进入选择界面:
1------------------------------手动生成迷宫
2------------------------------自动生成迷宫
3------------------------------迷宫行列数输入有误,选择重新输入
请输入选择:
在输入选择后输入数字选择执行不同的功能。
要求输入在可操作范围内的行、列数,可执行1、2操作。
执行显示迷宫每次的遍历过程。
显示生成的迷宫及路径。
七、测试结果
1、输入密码13,输入错误,重新输入1234
图3登陆界面图
2、输入迷宫行、列数5、56,超过预设范围,重新输入5、5
图4输入行列数图
3、进入选择界面:
1进入手动输入,输入迷宫
图5初始化迷宫图
4、显示输出结果
图6建立迷宫图图7结果运行图1
图8结果运行图2图9结果运行图3
图10路径查找结果图
选择2进入自动生成迷宫。
图11选择图
自动生成迷宫
图12生成过程图
显示输出结果
图13迷宫求解过程图1图14迷宫求解过程图2
图15迷宫求解过程图3图16迷宫求解过程图4
图17路径查找结果图
八、参考文献
[1]王昆仑,李红.《数据结构与算法.》北京:
中国铁道出版社,2006年5月。
[2]李春葆《数据结构教程》北京:
清华大学出版社2005年1月。
源代码:
#include"
iostream"
stdlib.h"
usingnamespacestd;
#defineN50
#defineM50
intmaze[N+2][M+2];
structpoint{introw,col,predecessor;
}queue[512];
//
inthead=0,tail=0;
voidshoudong_maze(intm,intn){//手动生成迷宫函数
system("
cls"
);
inti,j;
//控制循环变量
printf("
选择手动生成迷宫\n"
0表示通路,1表示障碍\n"
请按行、列数,对应输入0、1\n"
for(i=0;
i<
m;
i++)
for(j=0;
j<
n;
j++)
scanf("
%d"
&
maze[i][j]);
}
voidzidong_maze(intm,intn){//自动生成迷宫函数
自动生成迷宫\n"
生成中……\n"
system("
pause"
//暂停
for(i=0;
for(j=0;
maze[i][j]=0+(int)(2*rand()/(RAND_MAX+1.0));
//0、1随机数产生,生成迷宫}
voidprint_maze(intm,intn)//生成迷宫打印
{inti,j;
i++){
printf("
\n"
printf("
maze[i][j]);
}
{system("
生成结果\n"
迷宫入口\n"
↓"
print_maze(m,n);
→迷宫出口\n"
voidresult_maze(intm,intn)//迷宫生成图形
迷宫生成图形如下所示:
{if(maze[i][j]==0||maze[i][j]==2)printf("
"
if(maze[i][j]==1)printf("
■"
if(maze[i][j]==3)printf("
□"
}}
voidenqueue(structpointp)
{queue[tail]=p;
tail++;
structpointdequeue(void)
{head++;
returnqueue[head-1];
intis_empty(void)
{returnhead==tail;
voidvisit(introw,intcol,intmaze[52][52])//访问节点
{structpointvisit_point={row,col,head-1};
maze[row][col]=2;
enqueue(visit_point);
intmgpath(intmaze[52][52],intm,intn)
{structpointp={0,0,-1};
if(maze[p.row][p.col]==1){
此迷宫无解\n\n"
return0;
maze[p.row][p.col]=2;
enqueue(p);
while(!
is_empty()){
p=dequeue();
if(p.row==m-1/*goal*/
&
&
p.col==n-1)
break;
if(p.col+1<
n/*right*/
maze[p.row][p.col+1]==0)
visit(p.row,p.col+1,maze);
if(p.row+1<
m/*down*/
maze[p.row+1][p.col]==0)
visit(p.row+1,p.col,maze);
if(p.col-1>
=0/*left*/
maze[p.row][p.col-1]==0)
visit(p.row,p.col-1,maze);
if(p.row-1>
=0/*up*/
maze[p.row-1][p.col]==0)
visit(p.row-1,p.col,maze);
\n--
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 迷宫 问题 课程设计 报告