1、编程实训实验报告书专 业:计算机科学与技术 班 级: 1 班 学 号: 31960144 姓 名:周* 指导教师:周* 日 期:2016 年 6月 30日 目录一、需求分析31.任务要求32.软件功能分析33.数据准备3二、概 要设计31.功能模块图42.模块间调用关系43.主程序模块54.抽象数据类型描述5三、详细 设计61.存储结构定义62.各功能模块的详细设计7四、实现和 调试71.主要的算法72.主要问题及解决83.测试执行及结果8五、改进9六 、附录91 需求分析 1.1 任务要求 以一个 m*n的长方阵表示迷宫,和分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条
2、从入口到出口的通路,或得出没有通路的结论。1.2 软件功能分析设计一个迷宫,通过该程序可以找出通往出口的最短路径。程序功能有三()创建迷宫;()求解迷宫;()输出迷宫的解。1.3 数据准备迷宫的测试数据如下:左上角(1,1)为入口,右下角(9,8)为出口。0 0 1 0 0 0 1 00 0 1 0 0 0 1 00 0 0 0 1 1 0 10 1 1 1 0 0 1 00 0 0 1 0 0 0 00 1 0 0 0 1 0 10 1 1 1 1 0 0 11 1 0 0 0 1 0 11 1 0 0 0 0 0 0障碍物坐标:1 3 1 7 2 3 2 7 3 5 3 6 3 84 2
3、4 3 4 4 4 7 5 4 6 2 6 66 8 7 2 7 3 7 4 7 5 7 8 8 18 2 8 6 8 8 9 1 9 22 概要设计2.1 功能模块图栈的顺序存储表示#define StackSize 100 /假定预分配的栈空间最多为 100个元素typedef char DataType;/假定栈元素的数据类型为字符typedef structDataType dataStackSize;int top;SeqStack;基本操作的算法描述(1) 置栈空void InitStack(SeqStack *S)/将顺序栈置空S-top=-1; (2) 判栈空int Stack
4、Empty(SeqStack *S)return S-top=-1;(3) 判栈满int StackFull(SeqStack *SS)return S-top=StackSize-1;(4) 进栈void Push(S,x)if (StackFull(S)Error(“Stack overflow“); /上溢,退出运行S-data+S-top=x;/栈顶指针加 1后将 x入栈(5) 退栈DataType Pop(S)if(StackEmpty(S)Error(“Stack underflow“); /下溢,退出运行return S-dataS-top-;/栈顶元素返回后将栈顶指针减 1(6
5、) 取栈顶元素DataType StackTop(S)if(StackEmpty(S)Error(“Stack is empty“);return S-dataS-top;2.2 模块间调用关系Stack.h中调用的 base.h#include #include #include #define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;2.3 主程序模块主程序 maze.c中调用的 stack.h#define INIT_SIZE 100 /存储空间初始分配量#
6、define INCREMENT 10 /存储空间分配增量typedef struct /迷宫中 r行 c列的位置int r;int c;PostType;typedef structint ord; /当前位置在路径上的序号PostType seat;/当前坐标int di; /往下一坐标的方向SElemType; /栈元素类型typedef structSElemType* base;/栈基址,构造前销毁后为空SElemType* top;/栈顶int stackSize; /栈容量Stack; /栈类型Status InitStack(Stack if(!S.base)exit(OVER
7、FLOW);/存储分配失败S.top=S.base;S.stackSize=INIT_SIZE;return OK;/InitStackStatus StackEmpty(Stack S) /若 s为空返回 TRUE,否则返回 FALSEif(S.top=S.base)return TRUE;return FALSE;/StackEmptyStatus Push(Stack if(!S.base)exit(OVERFLOW); /存储分配失败S.top=S.base+S.stackSize;S.stackSize+=INCREMENT;*S.top+=e;return OK;/pushStat
8、us Pop(Stack e=*-S.top;return OK;/PopStatus DestroyStack(Stack S.top=S.base;return OK;/DestroyStack2.4 抽象数据类型描述栈(stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有特殊含义,称为栈顶(top),相应的,表头端称为栈底(bottom) 。不含元素的空表称为空栈。假设栈 S=(a1,a2,,an) ,则称 a1为栈底元素,an 为栈顶元素。栈的修改是按后进先出的原则进行的。因此,栈又称为后进先出(List In First Out)的线性表。在迷宫问题中,假设
9、以栈 S记录“当前路径” ,则栈顶中存放的是“当前路径上最后一个通道块” 。由此, “纳入路径”的操作即为“当前位置入栈” ;“从当前路径上删除前一通道块”的操作即为“出栈” 。3 详细设计3.1 存储结构定义typedef int Status;#define INIT_SIZE 100 /存储空间初始分配量#define INCREMENT 10 /存储空间分配增量typedef struct /迷宫中 r行 c列的位置int r;int c;PostType;typedef structint ord; /当前位置在路径上的序号PostType seat;/当前坐标int di; /往下
10、一坐标的方向SElemType;/栈元素类型typedef structSElemType* base;/栈基址,构造前销毁后为空SElemType* top;/栈顶int stackSize; /栈容量Stack;/栈类型3.2 各功能模块的详细设计 初始化迷宫Status InitMaze(MazeType #define INIT_SIZE 100 /存储空间初始分配量#define INCREMENT 10 /存储空间分配增量typedef struct /迷宫中 r行 c列的位置int r;int c;PostType;typedef structint ord; /当前位置在路径上
11、的序号PostType seat;/当前坐标int di; /往下一坐标的方向SElemType;/栈元素类型typedef structSElemType* base;/栈基址,构造前销毁后为空SElemType* top;/栈顶int stackSize; /栈容量Stack;/栈类型Status InitStack(Stack if(!S.base)exit(OVERFLOW);/存储分配失败S.top=S.base;S.stackSize=INIT_SIZE;return OK;/InitStackStatus StackEmpty(Stack S) /若 s为空返回 TRUE,否则返
12、回 FALSEif(S.top=S.base)return TRUE;return FALSE;/StackEmptyStatus Push(Stack if(!S.base)exit(OVERFLOW); /存储分配失败S.top=S.base+S.stackSize;S.stackSize+=INCREMENT;*S.top+=e;return OK;/pushStatus Pop(Stack e=*-S.top;return OK;/PopStatus DestroyStack(Stack S.top=S.base;return OK;/DestroyStack#define MAXLE
13、N 10/迷宫包括外墙最大行列数目typedef structint r;int c;char adrMAXLENMAXLEN;/可取 * #MazeType; /迷宫类型Status InitMaze(MazeType printf(“输入行和列数: “);scanf(“%d%d“, /迷宫行和列数for(i=0;imaze.r | nmaze.c)/越界exit(ERROR);maze.adrmn=1;/迷宫障碍用#标记printf(“输入障碍物坐标,以-1 -1 结束: “);scanf(“%d%d“,/whilereturn OK;/InitMaze Status Pass(MazeT
14、ype maze,PostType curpos)/当前位置可通则返回 TURE,否则返回 FALSEif(maze.adrcurpos.rcurpos.c= )/可通return TRUE;elsereturn FALSE;/PassStatus FootPrint(MazeType /“*“表示可通return OK;/FootPrintPostType NextPos(PostType cpos=curpos;switch(i) /1.2.3.4分别表示东,南,西,北方向case 1 : cpos.c+=1; break;case 2 : cpos.r+=1; break;case 3
15、: cpos.c-=1; break;case 4 : cpos.r-=1; break;default: exit(ERROR); return cpos;/NextposStatus MarkPrint(MazeType /“表示曾走过但不通return OK;/MarkPrintStatus MazePath(MazeType PostType curpos;int curstep;/当前序号,1.2.3.4 分别表示东,南,西,北方向SElemType e;InitStack(S);curpos=start; /设置“当前位置“为“入口位置“curstep=1; /探索第一步doif(
16、Pass(maze,curpos)/当前位置可以通过,/即是未曾走到过的通道FootPrint(maze,curpos);/留下足迹e.ord=curstep;e.seat=curpos;e.di=1;Push(S,e); /加入路径if(curpos.r=end.relse return TRUE; /到达出口elsecurpos=NextPos(curpos,1); /下一位置是当前位置的东邻curstep+; /探索下一步/else/ifelse /当前位置不通if(!StackEmpty(S)Pop(S,e);while(e.di=4 Pop(S,e); /留下不能通过的标记,并退一步
17、/whileif(e.di maze.r | start.cmaze.c)printf(“nBeyond the maze!n“);continue;while(start.rmaze.r | start.cmaze.c);do /输入迷宫出口坐标printf(“n输入出口坐标: “);scanf(“%d%d“,if(end.rmaze.r | end.cmaze.c)printf(“nBeyond the maze!n“);continue;while(end.rmaze.r | end.cmaze.c);if(!MazePath(maze,start,end)/迷宫求解printf(“n没有路径!n“);elsePrintMaze(maze);/打印路径printf(“n继续?(y/n): “);scanf(“%s“,while(cmd=y | cmd=Y);return 0;