1、实 验 报 告课程名称 数据结构 实验名称 迷宫最短路径 实验类型 综合型 实验地点 计 405 机房 实验日期 2017.5.13 指导教师 魏海平 专业 软件工程 班级 软件 1601 学号 1611030102 姓名 寇春雷 辽宁石油化工大学计算机与通信工程学院数据结构实验报告评分表项目 要求 分数 有无项目()得分实验目的明确 5实验内容理解透彻 5程序总体框架设计完整 10完成相关辅助代码 5预习报告(30 分)实验方案设计完整合理测试方案合理 5发现问题 5实验过程(30 分) 问题的分析 15问题的解决方法 10内容翔实无缺漏 5如实记录实验过程 10实验报告(20 分)撰写规整
2、 5实验结果的分析 5实验总结(10 分) 按照结果对原实验方案的改进意见 5实验的收获 5实验体会(10 分) 实验内容的发散考虑 5总分实 验 二 迷宫最短路径题目:迷宫最短路径问题描述从一个迷宫的入口到出口找出一条最短路经。用一个二维数组 MAZE(1m,1n)模拟迷宫,数组元素为 0 表示该位置可以通过,数组元素为 1 表示该位置不可以通行。MAZE(1,1) 和MAZE(m,n) 分别为迷宫的入口和出口。基本要求(1)输入数据a.输入迷宫的大小 m 行和 n 列,两者为整数b.由随机数产生 0 或 1,建立迷宫。(2)输出数据首先输出模拟迷宫的二维数组,若存在最短路经,则由出口回朔到
3、入口打印这一条路径,如下所示: (m,n), , (i,j), , (1,1)如无通道,则打印:THERE IS NO PATH.实现提示(1)数据结构为了在程序中判断方便,把迷宫扩展成为 MAZE(0m+1,0n+1),扩展部分的元素设置为 1,相当于在迷宫周围布上一圈不准通过的墙,这样,在迷宫的任一位置(I,j)上都有八个可以移动的方向。用二维数组 MOVE(18,12)存放八个方向上的位置量,如图所示:(i+MOVE1,1, j+MOVE1,2)(i+MOVE8,1, j+MOVE8,2) (i+MOVE2,1, j+MOVE2,2) (i+MOVE7,1, j+MOVE7,2) (i+
4、MOVE3,1, j+MOVE3,2) (i+MOVE6,1, j+MOVE6,2) (i+MOVE4,1, j+MOVE4,2) (i+MOVE5,1, j+MOVE5,2) MOVE 的设置情况i j1 21 -1 02 -1 13 0 14 1 15 1 06 1 -17 0 -18 -1 -1为了标志已经通过的位置,采用一个标志数组 MARK(1m,1n)初值为 0,在寻找路径的过程中,若通过了位置(i,j ) ,则将 MARK(i,j)置为为 1。为了记录查找过程中到达位置及其前一位置,建立一个 Q(1m*n-1, 02)数组,对于某一个数组元素 Q(P),其中,Q(P,0)和 Q(
5、P,1)记下到达位置 i 和 j,Q(P,2) 记下其出发点在 Q 数组中的下标。(2)算法基本思想将入口(1,1)作为第一个出发点,依次在八个反方向上搜索可通行的位置,形成第一层新的出发点,然后对第一层中各个位置分别搜索他所在八个方向上的可通行位置,形成第二层新的出发点,如此进行下去,直至达到出口(m,n)或者迷宫所有位置都搜索完毕为止。具体实施:从(m,n)开始,将其记入 Q 数组,比如记入 Q(1),以它作为第一个出发点,依次对八个方向进行搜索,若下一个位置(I,j)可通行并且尚未经过(即 MAZE(i,j)=0 且MARK(i,j)=0) ,则记入 Q 数组,如记在 Q(P),则在 Q
6、(P,2)中要记下其出发点在 Q 数组中的下标 1,在八个方向上都搜索过以后,根据先进先出的原则 Q 从数组中重新取出一个位置作为新的出发点(这里,我们实际上把 Q 数组作为一个顺序表示的队列) ,重复以上过程,若能达到位置(m ,n) ,表示找到最短路径;若 Q 数组中已经没有位置可以作为新的出发点了,则表示迷宫没有通路。4.需求分析(1)以二维数组 mazeM+2N+2表示迷宫,其中 mazei0和 mazeiN+1(0=0数据关系:R1 | a(i-1),aiD,i = 2,3n基本操作:InitStack( struct mark start,end; /start,end 入口和出口
7、的坐标 int add42=0,1,1,0,0,-1,-1,0;/行增量和列增量 initmaze(sto);/建立迷宫 printf(“输入入口的横坐标,纵坐标逗号隔开n“); scanf(“%d,%d“, printf(“输入出口的横坐标,纵坐标逗号隔开n“); scanf(“%d,%d“, MazePath(start,end,sto,add); /find path system(“PAUSE“); (2) 栈模块 实现栈抽象数据类型;(3) 迷宫模块 实现迷宫抽象数据类型,建立迷宫,求解迷宫的一条路径。7.源程序代码:#include “stdafx.h“#include #incl
8、ude#includeint * CreateArr(int m, int n)/创建动态全局二维数组int i;int *p;p = (int*)malloc(sizeof(int*)*m);for (i = 0; i =1;i-)j=0;printf(“(%d,%d),“,Qij,Qij+1);printf(“n“); void backtrack(int x,int y,int step,int m,int n)MARKxy=1;int w,v;if(x=m Qstep0=x;Qstep1=y;print(step);return;elsefor( w=1;w=-1;w-)for( v=
9、1;v=-1;v-)if(w!=0 | v!=0) x+=w;y+=v;step+;/第w,v个值可选Qstep0=x;Qstep1=y;if(MARKxy=0 step-;x-=w;y-=v;return;int main()int m,n;printf(“请输入迷宫的行数:nm=“);scanf_s(“%d“,printf(“请输入迷宫的列数:nn=“);scanf_s(“%d“,MAZE = CreateArr(m + 2, n + 2);MARK = CreateArr(m + 2, n + 2);Q = CreateArr(m * n, 2); srand(unsigned)time
10、(NULL);int i,j,p;for(i=0;i=n+1;i+)/第0行用 MAZE0i=-5;MAZEm+1i=-5;for(i=0;i=m+1;i+)/第0列不用 MAZEi0=-5;MAZEin+1=-5;for(i=1;im+1;i+)/其余的随机生成0或1 for(j=1;jn+1;j+)p=rand()%10%2;/x的值为0或1 MAZEij=p;MAZE11=0;/入口为0 MAZEmn=0;/出口为0 for(i=1;im+1;i+)/0行0列不显示 for(j=1;jn+1;j+)printf(“%d “,MAZEij);printf(“n“);/递归中超界,对MARK
11、特殊处理for(i=1;im+1;i+)/MARK全体置为零for(j=1;jn+1;j+)MARKij=0;for(i=0;i=m+1;i+)MARKin+1=1;MARKi0=1;for(i=0;i=n+1;i+)MARKm+1i=1;MARK0i=1;MARK11=1;Q10=1;Q11=1;backtrack(1,1,1,m,n);printf(“n“);if(flag=0)printf(“THERE IS NO PATH.n“);return 0; 8程序截图:9. 实验总结1、开始没有将 Mnm.start.end 设置为 MAZE 型数据的下属单元,使得各个迷宫操作的函数参数十分
12、散杂,调试时各参数关系不易把握。2、另行设置 Print 函数,使得终端输出更加友好,并巧妙地将迷宫以特殊、明朗的字符输出,效果更好。3、开始的条件没有控制好,导致输出时不是完整路径,甚至出错。4、选择方向时有一定策略,开始选择时按照顺时针依次读取方向,发现太耗时且效果不好,容易出现不必要的弯折走法,后来通过控制方向顺序,即第一方向为东南方,然后再东方、南方.,选取越靠近出口的方向为优先方向,因为这样的话搜索路径时自然会本着路径最短的原则向出口处行进,那么找到的路径自然是最短路径(之一) 。5、由于八个方向的特殊性,根据方向的顺序,搜索路径时仍会出现多走的情况,比如先往东再往西南,其实是可以直
13、接往南的,因此为了避免这种情况,在入栈时还要先进行这种情况的判断,如是这种情况则出栈将前一位置方向改变再入栈。6、为了便于找到最短路径,起初只使用了靠近出口处的五个方向,但是发现有特殊情况存在时由于不能想远离出口的方向行进而找不到路径,因此在搜索路径时进行了两次搜索,第一次使用五个靠进出口的方向搜索,找到路径时则返回,若未搜索到则再进行一次八个方向的搜索,即为了防止漏掉特殊情况,找到时则返回,由于第一搜索无结果若第二次搜索到路径也只能是特殊情况,故也应该是最短路径(之一) 。7、最大的问题是并没有按照题目要求来做,因为题目中要求用队列来存储路径。10. 实验心得体会根据我在课程设计中遇到得问题
14、,我将在以后的学习过程中注意以下几点:1、认真上好专业实验课,多在实践中锻炼自己。2、写程序的过程中要考虑周到,严密。3、在做设计的时候要有信心,有耐心,切勿浮躁。4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运用。5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。每个实验通常都要花费很久的时间才能理清一个程序的思路,而且要不断的调试程序才能把程序调试正确,同时还要做到界面的输出也是需要美化的。这次课程设计终于顺利完成了,在设计中遇到了很多专业知识问题,最后在老师的辛勤指导下,也完成了课程设计。通过这次的课程设计,让我更加了解到数据结构的重要性。以及它对我们专业的发展发挥的作用。对我们而言,知识上的收获很重要,但精神上的丰收更加可喜。让我知道了学无止境的道理。我们每一个人永远不能满足于现有的成就。这次课程设计必将成为我人生旅途上一个非常美好的回忆!同时在做课程设计时要能够从多方面去考虑,去研究,用多种算法去实现要求。此次课程设计,学到了很多课内学不到的东西,比如独立思考解决问题,出现差错的随机应变,这些都让我受益非浅,今后的制作应该能够更轻松,自己也都能够解决并高质量的完成项目。