迷宫问题课程设计报告Word文档下载推荐.docx
《迷宫问题课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《迷宫问题课程设计报告Word文档下载推荐.docx(26页珍藏版)》请在冰豆网上搜索。
实现了查找路径。
宫路由算法流程图:
N
N
YY
Y
Y
图1迷宫路由算法流程图
1、数据输入形式和输入值的范围:
生成迷宫时可选择手动或者自动生成;
手动输入迷宫矩阵时以0表示无障碍为通路,1表示该点有障碍为墙。
所有输入中,元素的值均为整数。
2、结果的输出形式:
当完成迷宫生成后,会提示输入入口与出口,进入迷宫路由查找算法,如找到出口,则打印出路径矩阵坐标,并显示显示迷宫生成图形
3、测试数据:
a、进入界面,选择2,自动生成
b、输入入口与出口
c、查看结果
三、概要设计
1、为了实现上述功能,需要:
①构造一个二维数组maze[M+2][N+2]用于存储迷宫矩阵,构造一个二维数组backup[M+2][N+2]用于备份迷宫矩阵;
②自动或手动生成迷宫,即为二维数组maze[M+2][N+2]赋值并备份;
③将构造一个堆栈用于存储迷宫路由;
④建立迷宫节点structMlink,用于存储迷宫中每个访问过的节点。
⑤实现迷宫路由算法,用深度优先遍历实现查找迷宫路径。
如找到路径则显示路径,否则提示无通路。
同时显示生成迷宫。
⑥在屏幕上显示操作菜单。
2、本程序包含6个函数:
(1)主函数main()
(2)生成迷宫函数create()
(3)打印迷宫矩阵与图形函数prin()
(4)寻找迷宫路由Mazepath()
(5)输出迷宫通路坐标printonglu1()
(6)输出迷宫生成图形printonglu2()
各函数之间的关系如下图(图2)所示:
函数关系图:
create()
prin()
main()Mazepath()
printonglu1()
printonglu2()
图2各函数间关系图
四、详细设计
实现概要设计中定义的所有数据类型,对各个操作给出伪代码算法。
对于主程序和各个模块也给出相应的伪代码算法。
1、节点类型和指针类型
迷宫矩阵类型:
Mlink*stack;
全局变量堆栈,存储迷宫通路
intabc[M+2][N+2]辅助数组
intmaze[M+2][N+2];
迷宫矩阵
intbackup[M+2][N+2];
备份矩阵,便于操作,定义为全局变量
迷宫中节点类型及队列类型:
structMlink{introw,col;
structnode*next;
}Mlink;
2、迷宫的操作
(1)生成迷宫
voidcreate(intmaze[][N+2])
{定义变量i,j,flag;
srand((unsigned)time(NULL))以时间产生随机种子
利用for初始化迷宫矩阵与备份矩阵,包括边界全置为1
利用for将迷宫置为0
选择迷宫生成方式1为手动生成,2为自动生成,输入值并赋给flag
flag=1{
以i,j控制迷宫中行列数的循环输入
以0表示通路,以1表示障碍,给maze[i][j]赋值,不包括边界。
循环结束,完成迷宫生成}
flag=2{
定义变量i1,j1用以接收随机值
以i,j控制迷宫中行列数的循环赋值操作
以0表示通路,以1表示障碍
用for(c=1;
c<
=M*N;
c++){
i1=(int)(rand()%M)+1;
j1=(int)(rand()%N)+1;
maze[i1][j1]=int(rand()%2);
}随机定位矩阵一点,给maze[i1][j1]赋一个随机值,这样可以增加迷宫通路的概率,循环结束,完成迷宫生成}
以i,j控制迷宫中行列数的循环赋值操作,将maze[][]备份到backup[][];
}
(2)打印迷宫矩阵与字符图形
voidprin(intmaze[][N+2]){
此函数主要用于将迷宫矩阵显示出来
定义变量i,j,z;
for(z=1;
z<
=N;
z++)
{if(z<
10)
printf("
%d"
z);
else
%d"
}此语句用来标明列号
用for控制循环在第一重循环里,使用语句{
printf("
\n"
);
if(i<
10)printf("
i);
elseprintf("
}以此用来标明行号
以i,j控制迷宫中行列数的循环操作,将maze[i][j]显示出来
并用字符□,■分别代表可通与不可通}
(3)迷宫求解路由求解操作{
Mlink*p;
用以操作堆栈
①入口若不通,return(0)否则下一步
②将其入栈
③未找到出口并且堆栈不空{
1)栈顶位置以下是否可通,可通则返回②,否则2),
2)栈顶位置以上是否可通,可通则返回②,否则3),
3)栈顶位置以右是否可通,可通则返回②,否则4),
4)栈顶位置以左是否可通,可通则返回②,否则出栈并返回,}
④如果栈顶为出口,return
(1);
否则return(0);
(4)打印迷宫通路坐标
voidprintonglu1(){
Mlink*q;
q=stack
q不空{
输出q指向的坐标
q=q->
next}
(5)输出迷宫通路的字符图形
voidprintonglu2(){
此函数根据堆栈内栈顶与“次栈顶”的位置关系决定输出字符↑,←,→或↓,其中2=↑,3=←,4=→,5=↓所有的操作都是在备份矩阵backup[][]上。
出口位置输出㊣
inti,z,j;
Mlink*p=stack;
p不空{
if(p->
row>
p->
next->
row)backup[p->
row][p->
col]=5;
下一位置在下
elseif(p->
row<
col]=2;
下一位置在上
col>
col)backup[p->
col]=4;
下一位置在右
else;
下一位置在左}
利用for循环,i,j为循环控制变量输出备份矩阵backup[][]{
为0是输出“□”
为1是输出“■”
为2是输出“↑”
为3是输出“←”
为4是输出“→”
为5是输出“↓”
为6是输出“㊣”}
另外在输出语句上,与矩阵输出相同,标明了行号与列号(该功能为王教授所要求而后加的)}
3、主函数
voidmenu(){
定义迷宫数组矩阵maze[M+2][N+2]
定义辅助数组abc[M+2][N+2]以用来在可以在第一次产生迷宫中重复选择入口与出口
定义变量k以用来控制循环
定义整型变量x1,y1,用于存储入口。
定义整型变量x2,y2,用于存储出口。
定义整型变量x用于接收mazepash的返回值。
输入入口与出口。
如果x=1则条用函数{
printonglu1();
printonglu2();
否则提示无通路。
界面开始会显示:
1,手动建立
2,自动建立
按提示操作,输入入口与出口,回车即会看到结果
五、调试分析
在调试过程中,开始用堆栈实现了路径的查找并调试成功,但输出的结果仅仅只是路径坐标,看起来不形象,于是想到了用字符来表示图形并标出通路,虽然不是太完美,但比之之前好好多了
在实现这一算法过程,注意将访问过的节点进行标记,并且在遍历过程中对矩阵数组是“破坏性”遍历,在算法完成后,矩阵已被破坏,堆栈中会存用路径,为了再原矩阵中用字符图形表示出通路,在建立矩阵后会迷宫矩阵备份一下,当然或许会有更好的处理方法。
六、使用说明
程序名为迷宫.exe,运行环境为DOS,程序执行后显示:
建立迷宫矩阵(选择1或者2):
2,自动建立进
请输入您的选择:
在输入选择后输入数字选择执行不同的迷宫建立。
按要求输入入口与出口
七、测试结果
1主页面
图3主页面
2选择自动建立
图4迷宫自动生成中
3,自动生成迷宫,上面为数组矩阵,其中0可通,1障碍。
下面为字符图形,其中白色可通,黑色障碍,
图5打印出的迷宫矩阵与迷宫图形
4,根据提示输入入口与出口
图6输入入口与出口
5,回车后输出路径
图7打印出的迷宫路径
6,输入一个非“0”继续
图8输入非“0”继续走该迷宫
7,输入入口与出口,无通路
图9无通路
八、参考文献
[1]王昆仑,李红.《数据结构与算法.》北京:
中国铁道出版社,2007年6月。
附录:
源代码:
#include"
iostream"
stdio.h"
time.h"
malloc.h"
#defineM20
#defineN20
typedefstructnode//堆栈结构
{
introw;
//行
intcol;
//列
}Mlink;
//定义一个栈
//备份数组
/*********************************建立迷宫矩阵**************************/
voidcreate(intmaze[][N+2])//建立迷宫
inti,j,flag;
srand((unsigned)time(NULL));
//以时间产生随机种子
for(i=0;
i<
=M+1;
i++)
for(j=0;
j<
=N+1;
j++)
maze[i][j]=1;
//将四周置为1
for(i=1;
=M;
for(j=1;
{
maze[i][j]=0;
//初始化矩阵
backup[i][j]=0;
//初始化备份矩阵
}
\n1,手动建立\n2,自动建立\n请输入您的选择:
scanf("
&
flag);
if(flag==1)//手动建立迷宫
printf("
手动建立迷宫矩阵(0表示可通1表示障碍):
for(i=1;
for(j=1;
scanf("
maze[i][j]);
if(flag==2){//自动建立迷宫
intc,i1,j1;
for(c=1;
c++){//矩阵初始为“0”,随机选择位置赋予一个随机的0或1,
maze[i1][j1]=int(rand()%2);
//随机矩阵按照王教授的要求这样可以产生更多的“0”即通路
}
printf("
自动生成中……\n"
system("
pause"
for(j=1;
backup[i][j]=maze[i][j];
//备份数组矩阵
/***************************华丽的分割线*******************************/
/********************************打印迷宫矩阵*****************/
voidprin(intmaze[][N+2])
inti,j;
printf("
迷宫矩阵如下(0可通):
\n"
intz;
for(z=1;
z++)//在矩阵上方标明列号
}
for(i=1;
{
//矩阵左方标明行号
maze[i][j]);
\n迷宫图形如下(白色可通):
"
z++)//在图形上方标明列号
if(maze[i][j]==0)printf("
□"
if(maze[i][j]==1)printf("
■"
/*******************************分割线***************************/
intMazepath(intmaze[][N+2],intx1,intx2,inty1,inty2)
Mlink*p;
if(maze[x1][y1]==0){
p=(Mlink*)malloc(sizeof(Mlink));
p->
row=x1;
col=y1;
next=NULL;
stack=p;
//将入口放入堆栈
maze[stack->
row][stack->
col]=1;
//标志入口已访问
while((!
(stack->
row==NULL&
&
stack->
col==NULL))&
(!
row==x2&
col==y2)))//未找到出口并且堆栈不空
if(maze[stack->
col+1]==0)//下面位置可通
{
p=(Mlink*)malloc(sizeof(Mlink));
p->
row=stack->
row;
col=stack->
col+1;
next=stack;
//入栈
stack=p;
maze[stack->
//标记已访问
elseif(maze[stack->
col-1]==0)//上面可通
col-1;
row+1][stack->
col]==0)//右面可通
row+1;
col;
row-1][stack->
col]==0)//左面可通
row-1;
else//不可通返回上一点
if(stack->
next!
=NULL){//堆栈里布置一个顶点则出栈并返回循环
p=stack;
stack=stack->
next;
//出栈
free(p);
//释放空间
}
else//堆栈里只有一个顶点即入口,此时若释放空间出栈会使循环
{//控制语句无法比较(因为stack->
col,stack->
row都已不存在,)
stack->
row=NULL;
col=NULL;
if(stack->
col==y2)return
(1);
elsereturn(0);
elsereturn(0);
/****************************输出坐标通路*******************/
voidprintonglu1()
Mlink*q;
其中的一条通道为:
q=stack;
出口<
--"
while(q!
=NULL)
(%d%3d)<
q->
row,q->
col);
q=q->
入口\n"
/*******************************分割线**********************/
/**********************输出图形通路**************************/
//2时输出↑,3时输出←,4时输出→,5时输出↓
voidprintonglu2()
图形通路如下:
z++)//图形上方标明列号
p=stack;
backup[p->
col]=6;
while(p->
if(p->
col!
if(p->
row>
row)backup[p->
//下一节点在下
elseif(p->
//下一节点在上
//下一节点在右
elsebackup[p->
row][p-