用栈方法队列方法求解迷宫问题Word文档格式.docx
《用栈方法队列方法求解迷宫问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《用栈方法队列方法求解迷宫问题Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
}Elemtype;
typedefstruct//队列的类型定义
{Elemtypeelem[MAXSIZE];
intfront,rear;
intlen;
}SqQueue;
3.2模块设计
定义函数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]),实现,迷宫的输出。
4详细设计
(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,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"
|2、队列求解的迷宫路径|\n"
|3、退出系统|\n"
|*******************************************|\n"
\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("
路径:
DLmazepath(maze2,move);
default:
\t\t选择错误!
!
}
\t\n请选择(0-3).....\n"
}
\n\t\t非常感谢您的使用!
}
(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<
M+2;
i++)
for(j=0;
j<
N+2;
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;
}
5测试分析
测试数据及结果如下:
(1)系统友好界面输出
图5.1进入系统界面运行结果
(2)选择1,运行结果输出如下:
图5.2迷宫以及使用栈求解迷宫路径的输出
(3)选择2、3运行结果如下:
图5.3迷宫以及使用队列求解迷宫路径的输出
(4)选择3运行结果如下:
图5.3退出程序
根据结果分析:
利用栈求得的路径不一定是最短路径,而用队列求得的路径是最短路径。
6课程设计总结
课程设计终于在本组组员共同的努力下完成了。
通过本次课程设计让我对栈和队列这一章的知识有了进一步了解,也让我知道了用栈和队列实现迷宫问题的基本原理,知道了栈和队列的不同存储结构的定义和算法描述,同时也学会了编写简单的迷宫问题的程序。
选了题目之后,我感觉题目之前已经做过一点相关的实验,本以为很快就能搞好,
但是,真正做起来才感觉没有那么简单,让我更加意识到自己的不足,我所知道的,所懂的太少了。
在刚开始编程的时候,我感到有点迷茫,虽然懂得了其相应的算法和思想,但是却不知道要怎样安排程序的结构、以及什么方法将其功能实现,更不知道要从哪里开始着手进行。
老师说的没错,我们平时的学习中程序练习太少,写的太少,什么事不可能一蹴而就,都是通过一点一滴的锻炼慢慢积累起来的。
所以我觉得在以后的学习中,我会更加注重实践,注重多练,多积累,为自己的以后工作打下结实的基础。
参考文献
[1]黄同成,黄俊民,董建寅.数据结构[M].北京:
中国电力出版社,2008
[2]董建寅,黄俊民,黄同成.数据结构实验指导与题解[M].北京:
[3]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,2002
[4]刘振鹏,张晓莉,郝杰.数据结构[M].北京:
中国铁道出版社,2003
致谢
在这次课程设计的撰写过程中,我得到了许多人的鼓励和帮助,在此,我表示衷心的感谢。
首先,我要感谢我的指导老师黄同城老师,他在课程设计上给予我的很大的帮助,指导课程设计的具体实现方向。
并且为我分析部分比较难懂的地方,让我把此次课程设计做得更加完善。
在此期间,我对迷宫问题有了更深刻的认识,而且也明白了很多做课程设计需要注意的地方,让我变得更严谨。
然后,我要感谢我们第一大组组员们,在组内讨论时,他们各抒己见,思路发散,讨论时锱铢必较,正是因为这份热情,我们对这次的课程设计充满了激情,方向也很明确。
在汇报进程的时候,组内积极讨论,相互竞争,优缺互补,让我们的课程设计更加完美,让我们自己在讨论中知道自己的优点,认识自己的缺点,不断完善自己。
最后感谢我的母校———邵阳学院,谢谢母校为我们提供了这样一个环境,让同学们能相聚在一起,让我们有这样一起奋斗共同完成目标的经历。
附录
具体程序代码实现
#include<
stdio.h>
stdlib.h>
#defineM6
#defineN8
#defineMAXSIZE100
#defineMAXM*N
typedefstruct//栈的相关类型定义
{
intx,y,d;
//d下一步方向
}elemtype;
typedefstruct
{
elemtypedata[MAXSIZE];
inttop;
}Sqstack;
intx,y;
}item;
}Elemtype;
typedefstruct//队列的类型定义
Elemtypeelem[MAXSIZE];
}SqQueue;
/*栈函数*/
voidInitStack(Sqstack*s)//构造空栈
s->
top=-1;
}
intStackempty(Sqstacks)//判断栈是否为空
if(s.top==-1)
return1;
return0;
voidpush(Sqstack*s,elemtypee)//入栈
if(s->
top==MAXSIZE-1)
{printf("
Stackisfull\n"
return;
top++;
data[s->
top].x=e.x;
top].y=e.y;
top].d=e.d;
voidpop(Sqstack*s,elemtype*e)//出栈算法
{
top==-1)
Stackisempty\n"
e->
x=s->
top].x;
y=s->
top].y;
d=s->
top].d;
top--;
/*队函数*/
voidInitQueue(SqQueue*q)//队的初始化
q->
front=q->
rear=0;
len=0;
intQueueEmpty(SqQueueq)//判断队空
if(q.len==0)
elsereturn0;
voidGetHead(SqQueueq,Elemtype*e)//读队头元素
Queueisempty\n"
else
*e=q.elem[q.front];
voidEnQueue(SqQueue*q,Elemtypee)//入队
if(q->
len==MAXSIZE)
Queueisfull\n"
elem[q->
rear].x=e.x;
q->
rear].y=e.y;
rear].pre=e.pre;
rear=q->
rear+1;
len++;
voidDeQueue(SqQueue*q,Elemtype*e)//出队
len==0)
x=q->
rear].x;
e->
y=q->
rear].y;
pre=q->
rear].pre;
front+1;
len--;
voidSprint(inta[M+2][N+2])
inti,j;
迷宫为:
%2d"
a[i][j]);
voidZprintpath(Sqstacks)//输出迷宫路径,栈中保存的就是一条迷宫的通路
elemtypetemp;
M,N);
while(!
Stackempty(s))
pop(&
s,&
temp);
temp.x,temp.y);
}printf("
voidZmazepath(intmaze[M+2][N+2],itemmove[8])//栈的迷宫求解输出
Sqstacks;
intx,y,d,i,j;
InitStack(&
s);
//栈的初始化
temp.x=1;
temp.y=1;
temp.d=-1;
push(&
s,temp);
Stackempty(s))
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;
x=i;
y=j;
maze[x][y]=-1;
if(x==M&
&
y==N)
{Zprintpath(s);
return;
elsed=0;
}//if
elsed++;
}//while
}//while
迷宫无路\n"
return;
inti;
do
i=(q.elem[i]).pre;
}while(i!
=-1);
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;
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(&
maze1[x][y]=-1;
}//if
if(i==M&
j==N)
{DLprintpath(q);
return;
}
}//for
DeQueue(&
q,&
迷宫无路!
{inta,i,j,maze2[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,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}};
||\n"
|1、栈求解迷宫的路径|\n"
|2、队列求解的迷宫路径|\n"
|3、退出系统|\n"
|********************************************|\n"
\t\n\n请选择(0-3):
switch(a)
case1:
求解路径为:
case2:
\t\n请选择(0-3):
\n\t\t结束退出程序!