迷宫实验报告(共19页).doc
《迷宫实验报告(共19页).doc》由会员分享,可在线阅读,更多相关《迷宫实验报告(共19页).doc(19页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上一、 实验内容3、 迷宫问题。假设迷宫由m行n列构成,有一个出口和一个入口,入口坐标为(1,1),出口坐标为(m,n),试设计并验证以下算法:找出一条从入口通往出口的路径,或报告一个“无法通过”的信息。(1)用C语言实现顺序存储队列上的基本操作,然后利用该队列的基本操作找出迷宫的一条最短路径。(2)设计一个二维数组MAZEm+2n+2表示迷宫,数组元素为0表示该位置可以通过,数组元素为1表示该位置不可以通行。MAZE11、MAZEmn分别为迷宫的入口和出口。(3)输入迷宫的大小m行和n列,动态生成二维数组;由随机数产生0或1,建立迷宫,注意m*n的迷宫需要进行扩展,扩
2、展部分的元素设置为1,相当于在迷宫周围布上一圈不准通过的墙。(4)要求输出模拟迷宫的二维数组;若存在最短路径,则有出口回溯到入口(出队列并利用栈实现),再打印从入口到出口的这条路径,例如(1,1),.,(i,j),.,(m,n);若没有路径,则打印“No path”。(5)迷宫的任一位置(i,j)上均有八个可移动的方向,用二维数组Direction存放八个方向的位置偏移量。Direction82=0,1,1,1,0,-1,-1,-1,1,-1,1,0,-1,0,-1,1;(6) 为避免出现原地踏步的情况需要标志已经通过的位置,采用一个标志数组MARKm+2n+2,初值均为0,在寻找路径的过程中
3、,若通过了位置(i,j),则将MARKij置为1。(7) 为了记录查找过程中到达位置(i,j)及首次到达(i,j)的前一位置(i_pre,j_pre),需要记住前一位置(i_pre,j_pre)在队列中的序号pre,即队列中数据元素应该是一个三元组(i,j,pre)。(8) 搜索过程简单下:将入口MAZE11作为第一个出发点,依次在八个方向上搜索可通行的位置,将可通行位置(i,j,pre)入队,形成第一层新的出发点,然后依次出队,即对第一层中各个位置分别搜索它所在八个方向上的可通行位置,形成第二层新的出发点,.,如此进行下去,直至达到出口MAZEmn或者迷宫所有位置都搜索完毕为止。二、 实验过
4、程及结果一、 需求分析1、用栈的基本操作完成迷宫问题的求解,其中栈的基本操作作为一个独立的模块存在。2、以二维数组Mm+2n+2表示迷宫,Mij 表示迷宫中相应(i,j)位置的通行状态(0:表示可以通行,1:表示有墙,不可通行),完成迷宫的抽象数据类型,包括出口、入口位置等。3、用户从屏幕上输入迷宫,从键盘输入迷宫的大小,即迷宫的长和宽(由于控制台大小限制,输入的长宽需在50以下),完成对应迷宫的初始化。根据键盘输入的迷宫规格随机生成大小相同的迷宫,产生方块的地方为墙,无方块的地方可通过,如下例所示:如下所示:4、程序完成对迷宫路径的搜索,为了更好地显示出求解结果,如果存在路径,则以长方形形式
5、将迷宫打印出来,而不是只按步输出坐标,也便于检查路径的正确性,用特定符号标出迷宫的物理状态,其中字符“#”表示出口和入口,“”标记出可行的路径;如果程序完成搜索后没有找到通路,则提示用户“No Path!”。如图所示:5、 程序执行的命令: 创建初始化迷宫; 搜索迷宫; 输出搜索到的最短路径。二、 概要设计(按照题目要求应该用队列实现路径的存储,但操作过程中遇到很多困难未能解决,故选择栈的操作来实现路径的存储)1、迷宫的抽象数据类型定义:ADT Maze数据对象:D:=aij,Start,end|-20=aij20,Start,end(i,j)|0im+2,0jn+2,m,n0 数据关系:R=
6、length,width length=|ai-1,aijD i=1,m+2,j=1,n+2 width=|aijaij-1D基本操作: SetMaze(&M) 初始条件:M已经定义,M的下属单元二维数组M.Mazerow+2d+2已存在,M.start,M.end也已作为下属存储单元存在 操作结果:构成数据迷宫,用数值标识迷宫的物理状态,以0表示通路,以1表示障碍,由终端读取迷宫空间大小,各点处的具体物理状态及Start和End点位置,完成迷宫构建 Pass(M, CurPos) 初始条件:已知目前迷宫状态及当前位置 操作结果:完成相应的搜索任务,如果可行,则返回1 NextPos(CurP
7、os, directionr) 操作结果:返回CurPOS位置在方向direction上的下一位置 SameSeat(Path,row,col) 操作结果:若(row,col)位置是路径Path中的一个点,则返回TRUE PrintMaze(M) 初始条件:迷宫M已存在 操作结果:输出字符标示的迷宫 MazePath(M,&Path) 初始条件:迷宫M已存在 操作结果:搜索迷宫,用path返回搜索所得路径。如不存在,返回0 PrintPath(M,Path) 初始条件:迷宫M已存在 操作结果:迷宫M存在可行路径则将迷宫M及相应最短路径一起打印输出ADT MAZE; 本程序模块结构 主函数模块v
8、oid main()初始化迷宫和栈;创建迷宫;输出迷宫;搜索路径;输出路径; 栈模块实现栈抽象数据类型; 迷宫模块实现迷宫抽象数据类型;各模块之间的调用关系如下:主程序模块 迷宫模块 栈模块三、 详细设计1、基本数据类型操作 栈模块 typedef structint order;Position seat;int direction;SElemType;/步数、方向及位置/栈定义 typedef struct lnodeSElemType *base;SElemType *top;/设两指针便于判断栈是否为空int stacksize;/栈当前可使用的最大容量SqStack; 参数设置:#d
9、efine STACK_INIT_SIZE 100#define STACKINCRENT 10/-基本操作的算法描述-Status InitStack(SqStack &s) / 构造一个空栈S.base=(SelemType )malloc(STACK_INIT_SIZE*SizeOf(SelemType);if(!S.base)exit(OVERLOW); / 存储分配失败S.top=S.base;S.stacksize=STACK_INIT_SIZE;return ok;Status StackEmpty(Sqstack &S) / 若S为空返回TRUE,否则返回FALSEreturn
10、 S.base=S.top;Status GetTop(SqStack &S,Selemtype &e) / 栈不空,用e返回s的栈顶元素及OK,否则返回ERRORif(S.top=S.base)return ERROR;e=*(S.top-1);return ok; Status Push(Sqstack &S,SelemType &e) / 插入元素e为新的栈顶元素if(S.top-S.base=S.stacksize)/ 栈满追加存储空间S.base=(SelemType)realloc(S.base,(S.stacksize+STACKICREMENT)Sizeof(Selemtype
11、);if(!S.base) exit(OVERFLOW) / 存储分配失败S.top=S.base+S.stacksize; / 确定新的栈顶指针S.stacksize+=STACKINCREMENT;/ 已分配空间增加 *S.top+=*e;return ok;Status Pop(Sqstack &s,SelemType &e)/ 若栈不变,则删除栈顶元素,用e返回其值及ok,否则falseif(S.top=o=S.base)return ERROR;*e=*-S.top; / 顶指针减小,用e返回其数据return ok; 迷宫模块: 迷宫的数据类型 #define MAXLENGTH
12、50/ 迷宫的最大长度#define MAXWIDTH 50/ 屏幕宽度,迷宫的最大宽度/元素类型typedef int Status;typedef structint row;int col;Position;/位置坐标/迷宫定义typedef int ElemType;typedef struct MAZEElemType MazeMAXLENGTHMAXWIDTH;/ 迷宫的物理状态描述int length,width;/ 迷宫的大小Position start,end;/ 开始与结束位置与栈的单元类型相同MAZE;/ “迷宫”型数据迷宫模块中的基本操作Status semaze(MA
13、ZE &M)Printf(“Please input the length and width of the MAZE”);sanf(“rlength,width”);for(k=0;kMaze0k=1;for(j=0;jMazej0=1;for(j=0;jMazejwidth+1=1;for(k=0;kMazelength+1k=1;/设置迷宫围墙for(j=1;j=length;j+)for(k=1;kMazejk=rand()%2;/随机生成迷宫 M-length=length;M-width=width;M-start.row=1;M-start.col=1;M-end.row=M-l
14、ength;M-end.col=M-width;M-MazeM-start.rowM-start.col=M-MazeM-end.rowM-end.col=0;/入口和出口设置*/void PrintMaze(MAZE M) / 打印出迷宫,包括边界printf(迷宫入口:1,1-用#表示n);printf(迷宫出口:%d,%d-用#表示n,M.length,M.width);for(row=0;rowM.length+2;row+)for(col=0;colM.width+2;col+)if(row=1&col=1)|(row=M.length&col=M.width)printf(# );
15、/入口和出口用#表示elseprintf(%c ,M.Mazerowcol);printf(n);/ 用字符型打印输出(i,j)状态Status Pass( MAZE M,Position CurPos) / 判断迷宫中当前位置CurPos上能否通过/ 如果通过返回1 if (M.MazeCurPos.rowCurPos.col=0) return 1; / 如果当前位置是可以通过,返回1 else return 0; / 其它情况返回0Position NextPos(Position CurPos, int direction) /返回当前位置在direction方向上的下一位置Retur
16、nPos.row=CurPos.row+Directiondirection-10;ReturnPos.col=CurPos.col+Directiondirection-11; return ReturnPos;Status SameSeat(SqStack Path,int row,int col)/位置(row,col)在路径中时返回TRUEwhile(pPath.top)if(Path.basenum.seat.row=row&Path.basenum.seat.col=col)/路径某一步所在的位置return TRUE;num+;p+;return FALSE;Status Maz
17、ePath(MAZE M,SqStack *S) / 若迷宫maze中从入口 start到出口 end的通道,则求得一条存放在栈中/ (从栈底到栈顶),并返回SUCCESS;否则返回FAILcurpos=M.start; / 设定当前位置为入口位置curstep=1; / 探索第一步/第一次查找路径,设置5个方向(不远离!终点的五个方向),若找到则返回SUCCESSdo if(Pass(M,curpos) / 当前位置可通过,即是未曾走到过的通道块 M.Mazecurpos.rowcurpos.col= ; / 留下足迹 e.direction=1; e.order=curstep; e.se
18、at=curpos; Push(S,&e); / 加入路径 if(curpos.row=M.end.row&curpos.col=M.end.col) / 到达终点(出口) return SUCCESS; curpos=NextPos(curpos,1); / 下一位置在当前位置的右下方 curstep+; / 探索下一步 else / 当前位置不能通过 if(!StackEmpty(S) Pop(S,&e); while(e.direction=5&!StackEmpty(S) M.Mazecurpos.rowcurpos.col= ;/标记不能通过 Pop(S,&e); / 留下不能通过的
19、标记,并退回一步 / while if(e.direction5) e.direction+; GetTop(S,&te); if(e.direction=5&te.direction=2) Pop(S,&e); e.direction+; Push(S,&e); / 换下一个方向探索 curpos=NextPos(e.seat,e.direction); / 当前位置设为新方向的相邻块 / if / if / elsewhile(!StackEmpty(S);curpos=M.start; / 设定当前位置为入口位置curstep=1; / 探索第一步/如果第一次查找无结果则再进行一次八个方
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 迷宫 实验 报告 19
限制150内