数据结构课程设计迷宫问题.doc
《数据结构课程设计迷宫问题.doc》由会员分享,可在线阅读,更多相关《数据结构课程设计迷宫问题.doc(24页珍藏版)》请在咨信网上搜索。
数据结构课程设计 课程名称:数据结构 题 目:迷宫设计 系 别:软件学院 专 业:移动设备应用开发 班 级:15级移动1班 姓 名: 学 期:2016-2017第一学期 指导教师: 时 间:2016年12月 目录 第一部分 需求分析 第二部分 详细设计 第三部分 调试分析 第四部分 用户手册 第五部分 测试结果 第六部分 附录 第七部分 参考文献 一、 需求分析 1、对于给定的一个迷宫,给出一个出口和入口,找一条从入口到出口的通路,并把这条通路显示出来;如果没有找到这样的通路给出没有这样通路的信息。 2、可以用一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 3、编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。 4、手动设置迷宫是任意给定的,所以程序要能够对给定的迷宫生成对应的矩阵表示,所以程序的输入包括了矩阵的行数、列数、迷宫内墙的个数、迷宫内墙的坐标、所求的通路的入口坐标、出口坐标。 5、自动生成的迷宫原理很简单,因为0和1分别代表通道和障碍物,所以只需要随机生成0和1然后再给最外围都赋值为1,就形成了新的迷宫。 二、详细设计 1、计算机解迷宫通常用的是“穷举求解“方法,即从人口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。 可以二维数组存储迷宫数据,通常设定入口点的下标为(1,1),出口点的下标为(n,n)。为处理方便起见,可在迷宫的四周加一圈障碍。对于迷宫中任一位置,均可约定有东、南、西、北四个方向可通。 2、如果在某个位置上四个方向都走不通的话,就退回到前一个位置,换一个方向再试,如果这个位置已经没有方向可试了就再退一步,如果所有已经走过的位置的四个方向都试探过了,一直退到起始点都没有走通,那就说明这个迷宫根本不通。 3、所谓"走不通"不单是指遇到"墙挡路",还有"已经走过的路不能重复走第二次",它包括"曾经走过而没有走通的路"。 显然为了保证在任何位置上都能沿原路退回,需要用一个"后进先出"的结构即栈来保存从入口到当前位置的路径。并且在走出出口之后,栈中保存的正是一条从入口到出口的路径。 4、若当前位置“可通”,则纳入“当前路径”,并继续朝“下一位置”探索;若当前位置“不可通”,则应顺着“来的方向”退回到“前一通道块”,然后朝着除“来向”之外的其他方向继续探索;若该通道块的四周四个方块均“不可通”,则应从“当前路径”上删除该通道块。 所谓“下一位置”指的是“当前位置”四周四个方向(东、南、西、北)上相邻的方块。假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。由此,“纳入路径”的操作即为“当前位置入栈”;“从当前路径上删除前一通道块”的操作即为“出栈”。 5、找通路的程序的关键部分可以表示如下: do{ 若当前位置可通, 则{ 将当前位置插入栈顶; // 纳入路径 若该位置是出口位置,则算法结束; // 此时栈中存放的是一条从入口位置到出口位置的路径 否则切换当前位置的东邻方块为新的当前位置; } 否则 { 若栈不空且栈顶位置尚有其他方向未被探索, 则设定新的当前位置为: 沿顺时针方向旋转找到的栈顶位置的下一相邻块; 若栈不空但栈顶位置的四周均不可通, 则{ 删去栈顶位置; // 从路径中删去该通道块 若栈不空,则重新测试新的栈顶位置, 直至找到一个可通的相邻块或出栈至栈空; } } } while (栈不空); 6、程序中用的数据结构解析: ① 程序中用了顺序栈保存当前找到的路径,当前位置不可通时,可以出栈,退回到前一个位置再继续探索通路,栈的定义如下: struct SqStack { SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素为单位 }; // 顺序栈 ② 栈中元素的类型结构 程序中先定义了一个表示坐标的类型结构: struct PosType // 迷宫坐标位置类型 { int x; // 行值 int y; // 列值 }; 栈中元素的类型结构如下: struct SElemType // 栈的元素类型 { int ord; // 通道块在路径上的"序号" PosType seat; // 通道块在迷宫中的"坐标位置" int di; // 从此通道块走向下一通道块的"方向"(0~3表示东~北) }; 7、主函数的流程图 输出从起点到终点的坐标 显示当前含有通路的迷宫结构 输出没有这样的通路 输入所求通路的起点终点坐标 显示当前的迷宫的结构 设置内墙 设置外墙 输入迷宫的行数列数(包括外墙) 手动设置 自动生成 自动生成迷宫不需要进行设置内墙一步,其他都一样。 三、 调试分析 1、对于程序的设计由简单到复杂,先设计一个整体的轮廓然后再慢慢的增加程序的功能,这样能够有效的减少错误,功能慢慢的增加,在前一步的程序运行通过之后再继续增加功能,这样在检查错误的时候比较有目的性,提高写程序的效率。 2、对于程序中的错误,如果遇到说变量没有定义或者数据结构没定义的错误,可能是由于你在定义这种数据结构的变量时数据结构还没有定义,也就是说在定义此数据结构的变量的语句要放在声明这种结构体之后。 3、在写程序时要注意printf和scanf语句的格式,格式不对会得不到你想要的结果。 4、写程序时一定要瞻前顾后,前后一致,包括名称、数据类型等等。 四、用户手册 在使用程序时严格按照程序给出的提示一步一步来,下面给出程序正常执行的步骤: 1、程序会提示“请输入迷宫的行数,列数(包括外墙):”,这时就需要输入表示迷宫的二维数组的行数和列数,需要注意的是由于我们在迷宫周围加了一道墙,所以要输入的行列数要比实际表示迷宫的行列数多两行两列。 2、程序提示“请输入迷宫内墙单元数:”,此时需要输入迷宫中墙的数目。 3、程序提示“请依次输入迷宫内墙每个单元的行数,列数:”,此时要输入迷宫中所有墙的坐标,我们用数组中的一个元素来表示墙。 4、在输入了迷宫所有内墙的坐标后,程序会显示出迷宫的结构,然后程序会提示“请输入起点的行数,列数:”,此时需要输入所求通路的起点坐标。 5、程序提示“请输入终点的行数,列数:”,此时需要输入所求通路的终点的坐标。 6、终点坐标输入完毕之后,程序会显示出两种运行的结果,一种是输出了迷宫的结构,此时迷宫中已包含了所找的通路,用连续的数字表示出了通路在迷宫中是如何走的,此时迷宫中的-1表示找通路时走过的单元但是通路不通。 注意:再输入内墙单元的坐标是一定要细心,不要错输,也不要漏输。否则程序会出错。 五、测试结果 迷宫的测试数据如下:左上角(1,1)为入口,右下角(9,8)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 程序的测试结果为: 1、 程序的开始界面 六、附录(附有完整的源程序) 源程序如下: #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define STACKINCREMENT 10 #define STACK_INIT_SIZE 100//初始长度 typedef int Status; struct PosType // 坐标竖直为x,横为y { int x; int y; }; struct SElemType { int ord; //序号1,2,3,4,5,6....路径的序号 PosType seat; //坐标 int di; //移动方向:上下左右 }; struct SqStack { SElemType *base; SElemType *top; int stacksize; }; SqStack S; #define MAXLENGTH 30 typedef int MazeType[MAXLENGTH][MAXLENGTH]; // 将数组做成地图。 MazeType m; // 宏定义,定义一个数组地图 int curstep=2; // curstep代表的是足迹,走过的路 Status InitStack(SqStack &S) { S.base=(SElemType *)malloc(STACK_INIT_SIZE *sizeof(SElemType));//开空间,栈底是表头 if(!S.base) exit(OVERFLOW);//检查是否开辟成功 S.top=S.base;//设为空栈 S.stacksize=STACK_INIT_SIZE;//设置长度 return OK; } Status Pop(SqStack &S,SElemType &e)//得到栈顶元素 { if(S.base==S.top) return ERROR;//检查是否为空栈 ,若为空则没有栈顶 e=*--S.top; //栈的特殊存储方式 return OK; } Status StackEmpty(SqStack &S)//判断是否为空 { if(!S.base) return ERROR; if(S.base==S.top) return TRUE;//为空 else return FALSE; } Status Push(SqStack &S,SElemType e)//进栈 { if(S.top-S.base>=S.stacksize)//栈不满 { S.base=(SElemType *) realloc (S.base,(S.stacksize+STACKINCREMENT) * sizeof(SElemType));//开空间 if(!S.base) exit(OVERFLOW);//检查是否开空间成功 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e;//压进栈里面 return OK; } Status Pass(PosType a)//传参传的是当前位置的坐标 { //检查当前位置是墙还是通道 if(m[a.x][a.y]==0) { return OK; } else { return ERROR; } } Status FootPrint(PosType a)//对已经走过的路做成标记 1,2,3,4.。。 { m[a.x][a.y]=curstep; } PosType NextPos(PosType c,int di)//0-3上下左右 { //作用是移动一个位置,所以需要传进来位置,移动方向,毕竟位移量已经确定为1 PosType direc[4]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 c.x+=direc[di].x; c.y+=direc[di].y; return c; } void MarkPrint(PosType a)//走不通 { m[a.x][a.y]=-1;//此路不通 } void Print(int x,int y) //迷宫的输出 { int i,j; for(i=0;i<x;i++) { for(j=0;j<y;j++) { if(m[i][j]==1) printf("■"); else printf("匚"); } printf("\n"); } } void Print1(int x,int y)//有通路的迷宫的输出 { int i,j; for(i=0;i<x;i++) { for(j=0;j<y;j++) { if(m[i][j]==1) { printf("■"); } else if(m[i][j]==-1||m[i][j]==0) { printf("匚"); } else if(m[i][j]>=2) { printf("☆"); } } printf("\n"); } } Status MazePath(PosType start,PosType end)//找通路 { InitStack(S);//保存可以走的路径 SElemType e; PosType curpos=start;//curpos是指当前位置,将开始位置设为当前位置 do { if(Pass(curpos))//如果当前位置的序号为0,即此位置不是迷宫中的墙 即为能走的路。 { FootPrint(curpos);//留下标记 e.ord=curstep; //输出的时候的1,2,3,4,5 e.seat.x=curpos.x; e.seat.y=curpos.y;//将当前位置信息存入e中 e.di=0; Push(S,e);//将这一步记录,压进栈中 curstep++; //再走一步 和ord一个性质,路径的步数 if(curpos.x==end.x&&curpos.y==end.y) return TRUE;//如果已经是出口就完成栈的记录 curpos=NextPos(curpos,e.di);//否则就 走一步 } else//如果当前位置是走过得 意思就是它的 序号不是0 { if(!StackEmpty(S))//判断栈是不是空,不是空就后退到上一步 { Pop(S,e);//后退到上一步 curstep--; while(e.di==3&&!StackEmpty(S))// 后退直到 找到能走的路 { MarkPrint(e.seat); Pop(S,e); curstep--; } if(e.di<3)//0—3代表上下左右 { e.di++; Push(S,e); curstep++; curpos=NextPos(e.seat,e.di);//下一步怎么移动 } } } }while(!StackEmpty(S)); return FALSE; } void Auto_maze(int x,int y) { int i,j; printf("\n迷宫生成中……\n\n"); system("pause"); for(i=0;i<x;i++) for(j=0;j<y;j++) m[i][j]=rand()%2; } void GenerateMaze(int x,int y)//生成迷宫地图 { int i,j; int x1,y1;//障碍物坐标 for(i=0;i<y;i++) { m[0][i]=1; m[x-1][i]=1; } for(j=0;j<x;j++) { m[j][0]=1; m[j][y-1]=1; } for(i=1;i<x-1;i++) { for(j=1;j<y-1;j++) { m[i][j]=0; } } printf("输入迷宫里面阻碍物的个数:"); scanf("%d",&j); printf("请输入迷宫中障碍物坐标:\n"); for(i=0;i<j;i++) { scanf("%d%d",&x1,&y1); m[x1][y1]=1; } printf("************************************迷宫图**************************************\n"); Print(x,y); printf("************************************迷宫图**************************************\n"); } void Movingdirection(SElemType a)//用来显示迷宫通路怎么走的 { switch(a.di) { case 0: printf("%d%3d ↑\n",a.seat.x,a.seat.y); break; case 1: printf("%d%3d ↓\n",a.seat.x,a.seat.y); break; case 2: printf("%d%3d ←\n",a.seat.x,a.seat.y); break; case 3: printf("%d%3d →\n",a.seat.x,a.seat.y); break; } } void MazePathway(PosType begin,PosType end,int x,int y)//显示迷宫通路图 { SElemType a; SqStack T; InitStack(T); if(MazePath(begin,end)) { printf("迷宫通路如下图所示:\n"); Print1(x,y); while(!StackEmpty(S)) { Pop(S,a); Push(T,a); } printf("找到的路径用坐标表示如下:\n"); while(!StackEmpty(T)) { Pop(T,a); Movingdirection(a); } } else printf("迷宫中没有出路。\n"); } int main() { PosType begin,end; int x,y; int n; int i,j; while(1) { printf("*****************1.手动输入。*****************\n"); printf("*****************2.自动生成。*****************\n"); printf("*****************3.退 出。*****************\n"); printf("请输入:"); scanf("%d",&n); system("CLS"); switch(n) { case 1: printf("请输入迷宫的宽和长:"); scanf("%d%d",&x,&y); GenerateMaze(x,y); printf("请输入起点的坐标:"); scanf("%d%d",&begin.x,&begin.y); printf("请输入终点的坐标:"); scanf("%d%d",&end.x,&end.y); MazePathway(begin,end,x,y); break; case 2: printf("请输入迷宫的宽和长:"); scanf("%d%d",&x,&y); Auto_maze(x,y); for(i=0;i<y;i++) { m[0][i]=1; m[x-1][i]=1; } for(j=0;j<x;j++) { m[j][0]=1; m[j][y-1]=1; } Print(x,y); printf("请输入起点的坐标:"); scanf("%d%d",&begin.x,&begin.y); printf("请输入终点的坐标:"); scanf("%d%d",&end.x,&end.y); MazePathway(begin,end,x,y); break; case 3: exit(-1); } } return 0; } 七、参考文献 1、《数据结构(C语言版)》 严蔚敏 吴伟民 编著 清华大学出版社 2、讲课所用课件等等目 录 第一章 总 论 1 一、项目提要 1 二、可行性研究报告编制依据 2 三、综合评价和论证结论 3 四、存在问题与建议 4 第二章 项目背景及必要性 5 一、项目建设背景 5 二、项目区农业产业化经营发展现状 11 三、项目建设的必要性及目的意义 12 第三章 建设条件 15 一、项目区概况 15 二、项目实施的有利条件 17 第四章 建设单位基本情况 19 一、建设单位概况 19 二、研发能力 20 三、财务状况 20 第五章 市场分析与销售方案 21 一、市场分析 21 二、产品生产及销售方案 22 三、销售策略及营销模式 22 四、销售队伍和销售网络建设 23 第六章 项目建设方案 24 一、建设任务和规模 24 二、项目规划和布局 24 三、生产技术方案与工艺流程 25 四、项目建设标准和具体建设内容 26 五、项目实施进度安排 27 第七章 投资估算和资金筹措 28 一、投资估算依据 28 二、项目建设投资估算 28 三、资金来源 29 四、年度投资与资金偿还计划 29 第八章 财务评价 30 一、财务评价的原则 30 二、主要参数的选择 30 三、财务估算 31 四、盈利能力分析 32 五、不确定性分析 33 六、财务评价结论 34 第九章 环境影响评价 35 一、环境影响 35 二、环境保护与治理措施 35 三、环保部门意见 36 第十章 农业产业化经营与农民增收效果评价 37 一、产业化经营 37 二、农民增收 38 三、其它社会影响 38 第十一章 项目组织与管理 40 一、组织机构与职能划分 40 二、项目经营管理模式 42 三、技术培训 42 四、劳动保护与安全卫生 43 第十二章 可行性研究结论与建议 46 一、可行性研究结论 46 二、建议 47- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 迷宫 问题
咨信网温馨提示:
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【精****】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【精****】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【精****】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【精****】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
关于本文