




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、. 数据结构课程设计报告 题目:迷宫问题非递归求解 2010年 6月 4日目录 一. 实验内容.3二. 需求分析3三总体设计4四详细设计6五代 码10六. 测 试.15七. 总 结.17一. 实验内容任务:可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;要求:二.需求分析1.可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;要求:使用非递归算法。2.用户可以根据自己的需求进行输入所需的迷宫,其中1表示迷宫的墙壁,0表示迷宫的通路,从而建立自己的迷宫;3.用户还可以自己设计迷宫的入口坐标,当然也可以设计出口了;4.程序执行的命
2、令包括:(1)构造栈Stack, T 描述迷宫中当前位置的结构类型, LinkNode链表结点三个类,其中Stack是Linknode的友元类. (2)构造存取迷宫的二维指针GetMaze(int &m,int &n) (3)恢复迷宫Restore(int *maze,int m,int n) (4)在迷宫中寻找一条通路Mazepath(int *maze,int m,int n) (5)输出所找到的通路PrintPath() (6) 定义当前位置移动的4个方向move数组.三总体设计存储结构:首先用二维指针存储迷宫数据,迷宫数据由用户输入。一个以链表作存储结构的栈类型,然后编
3、写一个求解迷宫的递归或非递归程序。求得的通路以三元组(i,j,d)形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向(东、南、西、北四个方向所用代表数字,自行定义)。1从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。迷宫的入口点的下标为(1,1),出口点的下标为(m,n)。为处理方便起见,可在迷宫的四周加一圈障碍。对于迷宫的任一位置,均可约定有东、南、西、北四个方向可通。经过的位置把0变为-1,带输出迷宫路径后在恢复迷宫院士为止2
4、. 本程序有三个模块: 主程序模块 三个类模块即其对象:实现栈链表抽象数据类型; 迷宫二维指针单元模块:存储迷宫,寻路径,输出迷宫,恢复迷宫。(二)流程图存取迷宫GetMaze(int &m,int &n)求取一条路径MazePath()if(p.GetPop().x=q.GetPop().x&&p.GetPop().y=q.GetPop().y)输入迷宫的长和宽内容显示结果Printpath()迷宫无路经 END数组move用于更改方向,函数Push, PrintPath, Restore调用函数GetPop, Push,Pop恢复迷宫Restore()调用四
5、详细设计(一).基本算法:首先用二维指针存储迷宫数据,迷宫数据由用户输入。一个以链表作存储结构的栈类型,然后编写一个求解迷宫的递归或非递归程序。求得的通路以三元组(i,j,d)形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向(东、南、西、北四个方向所用代表数字,自行定义)。迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按东、南、西、北4个方向顺序试探下一个位置;如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果4方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。每前进或后退一步,都要进行判断:若前进到了出口处,则说明找到
6、了一条通路;若退回到了入口处,则说明不存在通路。用一个二维指针数组迷宫表示迷宫,数组中每个元素取值“0”(表示通路)或“1”(表示墙壁)。迷宫的入口点在位置(1,1)处,出口点在位置(m,n)处。设计一个模拟走迷宫的算法,为其寻找一条从入口点到出口点的通路。二维数组的第0行、第m+1行、第0列、第m+1列元素全置成“1”, 表示迷宫的外墙;第1行第1列元素和第m行第m列元素置成“0”, 表示迷宫的入口和出口;其余元素值用GetMaze函数获取.假设当前所在位置是(x,y)。沿某个方向前进一步,它可能到达的位置最多有4。如果用二维数组move记录4方向上行下标增量和列下标增量,则沿第i个方向前进
7、一步,可能到达的新位置坐标可利用move数组确定: x=x+moveloop0 y=y+moveloop1从迷宫的入口位置开始,沿图示方向顺序依次进行搜索。定义一个栈,按从入口到出口存取路径.在搜索过程中,每前进一步,如果有新位置入栈,则把上一个探索的位置存入栈中,当前位置”-1”(表示这个位置在通路上),并将该位置的坐标压入栈中。如果没有新位置入栈,则返回到上一个位置.到达出口后,最后一个位置入栈,输出路径,并回复路径.把-1变为0.总之,入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未
8、能到达出口,则所设定的迷宫没有通路。迷宫的入口点的下标为(1,1),出口点的下标为(m,n)。为处理方便起见,可在迷宫的四周加一圈障碍。对于迷宫的任一位置,均可约定有东、南、西、北四个方向可通。(二). 为实现算法,需要类的象数据类型:类及其对象:类 Stack 对象成员如下:Stack(); 构造函数,置空栈操作结果:构造一个空的栈S。Stack(); 析构函数 void Push(T e); 把元素data压入栈中T Pop(); 使栈顶元素出栈 T GetPop(); 取出栈顶元素 void Clear(); 把栈清空 bool empty(); 判断栈是否为空,如果为空则返回1,否则返
9、回0T类 迷宫中当前位置的结构类型: T对象成员如下:x; x代表当前位置的行坐标y; y代表当前位置的列坐标dir; 0:无效,1:东,2:南,3:西,4:北LinkNode类 链表结点: 对象成员如下:友元类 StackT dataLinkNode *next(三).函数调用关系main GetMaze Mazepath Empy() GetPop() Push() PrintPath() Restore() Pop() GetPop() Push()(四) 算法的时间、空间复杂度1)本算法在空间上主要开辟了一个二维指针,规模都是迷宫(m+2)*(n+2),一个是栈,一个是迷宫路径记录,输
10、出时候调用栈,在恢复迷宫。2)在时间上为简单的链表栈的存储结构,二维指针GetMaze, Restore两函数算法时间复杂度为O((m+2)*(n+2)), Mazepath,PrintPath为O(1),(m为行数,n为列数)。(五) UML图T+X:int+y:int+dir:int LinkNode+T dataStack+push(T e):void+T Getpop ( ):void+T pop ( )+empty ( ):bool+Stack ( )+Stack ( )+Clear ( ):void+nextLinkNodeLinkNode-top<<friend>
11、;>五代码/*以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),。*/#include<iostream>using namespace std;class T /定义描述
12、迷宫中当前位置的结构类型public: int x; /x代表当前位置的行坐标 int y; /y代表当前位置的列坐标 int dir; /0:无效,1:东,2:南,3:西,4:北;class LinkNode /链表结点 friend class Stack;public: T data; LinkNode *next;class Stackprivate: LinkNode *top; /指向第一个结点的栈顶指针public: Stack(); /构造函数,置空栈 Stack(); /析构函数 void Push(T e); /把元素data压入栈中 T Pop(); /使栈顶元素出栈 T
13、 GetPop(); /取出栈顶元素 void Clear(); /把栈清空 bool empty(); /判断栈是否为空,如果为空则返回1,否则返回0;Stack:Stack() /构造函数,置空栈 top=NULL;Stack:Stack() /析构函数void Stack:Push(T e) /把元素x压入栈中 LinkNode *P; P=new LinkNode; P->data=e; P->next=top; top=P;T Stack:Pop() /使栈顶元素出栈 T Temp; LinkNode *P; P=top; top=top->next; Temp=P
14、->data; delete P; return Temp;T Stack:GetPop() /取出栈顶元素 return top->data;void Stack:Clear() /把栈清空 top=NULL;bool Stack:empty() /判断栈是否为空,如果为空则返回1,否则返回0 if(top=NULL) return 1; else return 0;int move42=0,1,1,0,0,-1,-1,0; /定义当前位置移动的4个方向bool Mazepath(int *maze,int m,int n); /寻找迷宫maze中从(0,0)到(m,n)的路径
15、/到则返回true,否则返回falsevoid PrintPath(Stack p); /输出迷宫的路径void Restore(int *maze,int m,int n); /恢复迷宫int* GetMaze(int &m,int &n); /获取迷宫 /返回存取迷宫的二维指针int main() int m=0,n=0; /定义迷宫的长和宽 int *maze; /定义二维指针存取迷宫 maze=GetMaze(m,n); /调用GetMaze(int &m,int &n)函数,得到迷宫 if(Mazepath(maze,m,n) /调用Mazepath(
16、int *maze,int m,int n)函数获取路径 cout<<"迷宫路径探索成功!n" else cout<<"路径不存在!n" return 0;int* GetMaze(int &m,int &n)/返回存取迷宫的二维指针 int *maze; /定义二维指针存取迷宫 int i=0,j=0; cout<<"请输入迷宫的长和宽:" int a,b;cin>>a>>b; /输入迷宫的长和宽 cout<<"请输入迷宫内容:n&qu
17、ot; m=a; n=b; /m,n分别代表迷宫的行数和列数 maze=new int *m+2; /申请长度等于行数加2的二级指针 for(i= 0;i<m+2;i+) /申请每个二维指针的空间 mazei=new intn+2; for(i=1;i<=m;i+) /输入迷宫的内容,0代表可通,1代表不通 for(j=1;j<=n;j+) cin>>mazeij; for(i=0;i<m+2;i+) mazei0=mazein+1=1; for(i=0;i<n+2;i+) maze0i=mazem+1i=1; return maze; /返回存贮迷宫
18、的二维指针maze;bool Mazepath(int *maze,int m,int n)/寻找迷宫maze中从(0,0)到(m,n)的路径 /到则返回true,否则返回false Stack q,p; /定义栈p、q,分别存探索迷宫的过程和存储路径 T Temp1,Temp2; int x,y,loop; Temp1.x=1; Temp1.y=1; q.Push(Temp1); /将入口位置入栈 p.Push(Temp1); maze11=-1; /标志入口位置已到达过 while(!q.empty() /栈q非空,则反复探索 Temp2=q.GetPop(); /获取栈顶元素 if(!(
19、p.GetPop().x=q.GetPop().x&&p.GetPop().y=q.GetPop().y) p.Push(Temp2); /如果有新位置入栈,则把上一个探索的位置存入栈p for(loop=0;loop<4;loop+) /探索当前位置的4个相邻位置 x=Temp2.x+moveloop0; /计算出新位置x位置值 y=Temp2.y+moveloop1; /计算出新位置y位置值 if(mazexy=0) /判断新位置是否可达 Temp1.x=x; Temp1.y=y; mazexy=-1; /标志新位置已到达过 q.Push(Temp1); /新位置入栈
20、 if(x=(m)&&(y=(n) /成功到达出口 Temp1.x=m; Temp1.y=n; Temp1.dir=0; p.Push(Temp1); /把最后一个位置入栈 PrintPath(p); /输出路径 Restore(maze,m,n); /恢复路径 return 1; /表示成功找到路径 if(p.GetPop().x=q.GetPop().x&&p.GetPop().y=q.GetPop().y) /如果没有新位置入栈,则返回到上一个位置 p.Pop(); q.Pop(); return 0; /表示查找失败,即迷宫无路经void PrintPa
21、th(Stack p) /输出路径 cout<<"迷宫的路径为n" cout<<"括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向)n" Stack t; /定义一个栈,按从入口到出口存取路径 int a,b; T data; LinkNode *temp; temp=new LinkNode; /申请空间 temp->data=p.Pop(); /取栈p的顶点元素,即第一个位置 t.Push(temp->data); /第一个位置入栈t delete temp; /释放空间 while(!p.empty()
22、/栈p非空,则反复转移 temp=new LinkNode; temp->data=p.Pop(); /获取下一个位置 /得到行走方向 a=t.GetPop().x-temp->data.x; /行坐标方向 b=t.GetPop().y-temp->data.y; /列坐标方向 if(a=1) temp->data.dir=1; /方向向下,用1表示 else if(b=1) temp->data.dir=2; /方向向右,用2表示 else if(a=-1) temp->data.dir=3; /方向向上,用3表示 else if(b=-1) temp-&
23、gt;data.dir=4; /方向向左,用4表示 t.Push(temp->data); /把新位置入栈 delete temp; /输出路径,包括行坐标,列坐标,下一个位置方向 while(!t.empty() /栈非空,继续输出 data=t.Pop(); cout<<'('<<data.x<<','<<data.y<<','<<data.dir<<"," /输出行坐标,列坐标 switch(data.dir) /输出相应的方向 case 1:cout<<")n"break; case 2:cout<<")n"break; case 3:cout<<")n"break; case 4:cout<<")n"break; case 0:cout<<&
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 统计师考试复习策略试题及答案
- 2025债务转让股权合同书
- 2025个人服务合同模板
- 泰国旅游行程路线
- 2025年济南市合同备案指南
- 天津体育学院《影视文学鉴赏》2023-2024学年第二学期期末试卷
- 山东女子学院《畜牧试验设计与统计分析1》2023-2024学年第一学期期末试卷
- 山东工艺美术学院《音乐技能》2023-2024学年第二学期期末试卷
- 2025届四川成都青羊区外国语学校高考物理试题模拟题专练目录含解析
- 湖北省竹溪一中、竹山一中等三校2024-2025学年高三全真历史试题模拟试卷(3)含解析
- 2024年重庆两江新区某国有企业招聘笔试真题
- 离婚协议民政局贵州安顺(2025年版)
- 心脏骤停后高质量目标温度管理专家共识2024
- 高校讲师个人学术发展计划
- 睾丸切除术课件
- 2025 年陕西省初中学业水平考试仿真摸底卷英语试卷(含解析无听力部分)
- 职等职级设计理论与实践
- 中医药生物信息学知到课后答案智慧树章节测试答案2025年春浙江中医药大学
- 海姆立克急救技术操作流程及评分标准
- deepseek在科研机构知识管理中的应用实例
- 污水处理设施运维服务投标方案(技术标)
评论
0/150
提交评论