1、目 录摘 要 .1前 言 .2正 文 .31. 采用类 C 语言定义相关的数据类型 .32. 各模块的伪码算法 .33. 搜索算法流程图 .64. 调试分析 .75. 测试结果 .76. 源程序(带注释) .10总 结 .16参考文献 .17致 谢 .18附件 部分源程序代码 .190摘 要在现实生活中,会遇到很多很多关于迷宫这样很复杂、很难解决的问题的问题。如果人工去解决这些问题,会很麻烦,花很长的时间,甚至无法解决。假如用计算机去解决,可以通过手动生成迷宫,也可以通过计算机随机的产生迷宫,最终退出。而且可以很快的求解迷宫,找到从入口到出口的通路,或者当没有通路时,得出没有通路的结论。找出通
2、路之后,会显示出通路路经,而且以图示的方式显示出通路,这样会使人一目了然的看清此迷宫的通路。迷宫是一个矩形区域,可以使用二维数组表示迷宫,这样迷宫的每一个位置都可以用其行列号来唯一指定,但是二维数组不能动态定义其大小,我们可以考虑先定义一个较大的二维数组 mazeM+2N+2,然后用它的前 m 行 n 列来存放元素,即可得到一个 mn 的二维数组,这样(0,0)表示迷宫入口位置,(m-1,n-1)表示迷宫出口位置。关键词: 迷宫;通路;二维数组;路径1前 言随着社会经济的发展,信息化程度的不断深入,传统的人工求解迷宫问题已不能满足生活的需要。近几年,随着迷宫问题越来越复杂、科技也越来越发达,人
3、们逐渐的开始用计算机求解迷宫问题。迷宫问题很复杂,但是人们又不得不去研究这个问题,因为人们的生活中需要它,离不开它。在迷宫路径的搜索过程中,首先从迷宫的入口开始,如果该位置就是迷宫出口,则已经找到了一条路径,搜索工作结束。否则搜索其上、下、左、右位置是否是障碍,若不是障碍,就移动到该位置,然后再从该位置开始搜索通往出口的路径;若是障碍就选择另一个相邻的位置,并从它开始搜索路径。为防止搜索重复出现,则将已搜索过的位置标记为 2,同时保留搜索痕迹,在考虑进入下一个位置搜索之前,将当前位置保存在一个队列中,如果所有相邻的非障碍位置均被搜索过,且未找到通往出口的路径,则表明不存在从入口到出口的路径。这
4、实现的是广度优先遍历的算法,如果找到路径,则为最短路径。2正 文1. 采用类 c 语言定义相关的数据类型节点类型和指针类型迷宫矩阵类型:int mazeM+2N+2;为方便操作使其为全局变量迷宫中节点类型及队列类型:struct pointint row,col,predecessor que5122. 各模块的伪码算法1、迷宫的操作(1)手动生成迷宫void shoudong_maze(int m,int n)定义 i,j 为循环变量for(i0 且 mazep.rowp.col-1=0,说明未到迷宫左边界,且其左方有通路,则 visit(p.row,p.col-1,maze),将左方节点入
5、队标记已访问如果 p.row-10 且 mazep.row-1p.col=0,说明未到迷宫上边界,且其上方有通路,则 visit(p.row,p.col+1,maze),将上方节点入队标记已访问访问到出口(找到路径)即 p.row=m-1 且 p.col=n-1,则逆序将路径标记为 3 即 mazep.rowp.col=3;while(p.predecessor!=-1)p=queuep.predecessor; mazep.rowp.col=3;最后将路径图形打印出来。2.菜单选择while(cycle!=(-1)手动生成迷宫 请按:1自动生成迷宫 请按:2退出 请按:3scanf(“%d“
6、,switch(i) case 1:请输入行列数(如果超出预设范围则提示重新输入) shoudong_maze(m,n);print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n);5case 2 :请输入行列数(如果超出预设范围则提示重新输入)zidong_maze(m,n);print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n);case 3:cycle=(-1); break;63. 搜索算法流程图4. 调试分析a、调试中遇到的问题及对问题的解决方法在调试过程中,刚开始
7、系统自动生成的迷宫并不是随机的,而是每次生成的都一样;求解时,不能正确的得到结果,有时还会求错;输出的路径是乱的,而不是按顺序显示。出现上述问题之后,经过和同学的探讨研究,重写随机函数、修改语句、调换语句的位置等一次一次的试验,最终问题才得以解决。在调试过程中,首先使用的是栈进行存储,但是产生的路径是多条或不是最短路径,所以通过算法比较,改用此算法b、算法的时间复杂度和空间复杂度该算法的运行时间和使用系统栈所占有的存储空间与迷宫的大小成正比,迷宫长为 m,宽为 n,在最好情况下的时间和空间复杂度均为 O(m+n) ,在最差情况下均为 O(m*n) ,平均情况在它们之间5. 测试结果进入系统主菜
8、单:7选择 1,即手动生成迷宫,及生成后有通路的求解结果:8选择 2,系统自动生成迷宫,此迷宫无通路:9选择 2,系统自动生成迷宫,生成的有解迷宫的解:10选择 3,退出系统:6. 源程序(带注释)#include“stdlib.h“#include“stdio.h“#define N 39#define M 39int X;int mazeN+2M+2;struct pointint row,col,predecessor;queue512;int head=0,tail=0;void shoudong_maze(int m,int n) /手动生成迷宫int i,j;printf(“nn“
9、);printf(“请按行输入迷宫,0 表示通路,1 表示障碍:nn“);for(i=0;i=0)if(p.row-1=0)if(p.row=m-1printf(“迷宫路径为:n“);printf(“(%d,%d)n“,p.row,p.col);mazep.rowp.col=3;while(p.predecessor!=-1)p=queuep.predecessor;printf(“(%d,%d)n“,p.row,p.col);mazep.rowp.col=3;else printf(“n=n“);printf(“此迷宫无解!nn“);X=0;return 0;void main()int i
10、,m,n,cycle=0;while(cycle!=(-1) /主菜单14printf(“*n“); printf(“ 欢迎进入迷宫求解系统n“);printf(“ 设计者: 兰理工计算机 4 班赵永刚 n“);printf(“*n“);printf(“ 手动生成迷宫 请按:1n“);printf(“ 自动生成迷宫 请按:2n“);printf(“ 退出 请按:3nn“);printf(“*n“); printf(“n“);printf(“请选择你的操作:n“);scanf(“%d“,switch(i)case 1:printf(“n 请输入行数:“);scanf(“%d“,printf(“n
11、“);printf(“请输入列数:“);scanf(“%d“,while(m39)|(n39)printf(“n 抱歉,你输入的行列数超出预设范围(0-39,0-39), 请重新输入:nn“);printf(“请输入行数:“);scanf(“%d“,printf(“n“);printf(“请输入列数:“);scanf(“%d“,shoudong_maze(m,n);15print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n);printf(“nnPress Enter Contiue!n“);getchar();while(getch
12、ar()!=n);break;case 2:printf(“n 请输入行数:“);scanf(“%d“,printf(“n“);printf(“请输入列数:“);scanf(“%d“,while(m39)|(n39)printf(“n 抱歉,你输入的行列数超出预设范围(0-39,0-39), 请重新输入:nn“);printf(“请输入行数:“);scanf(“%d“,printf(“n“);printf(“请输入列数:“);scanf(“%d“,zidong_maze(m,n);print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n
13、);printf(“nnPress Enter Contiue!n“);getchar();while(getchar()!=n);break;case 3:cycle=(-1);break;default:printf(“n“);printf(“你的输入有误!n“);printf(“nPress Enter Contiue!n“);getchar();while(getchar()!=n);break;16总 结通过这段时间的课程设计,本人对计算机的应用,数据结构的作用以及 C 语言的使用都有了更深的了解。尤其是 C 语言的进步让我深刻的感受到任何所学的知识都需要实践,没有实践就无法真正理解
14、这些知识以及掌握它们,使其成为自己的财富。在理论学习和上机实践的各个环节中,通过自主学习和请教老师,我收获了不少。当然也遇到不少的问题,也正是因为这些问题引发的思考给我带了收获。从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不只如何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变,我发现无论是专业知识还是动手能力,自己都有很大程度的提高。在这段时间里,我对for、while 等的循环函数用法更加熟悉,逐渐形成了较好的编程习惯。在老师的指导帮助下,同学们课余时间的讨论中,这些问题都一一得到了解决。在程序的调试能力上,无形中得到了许多的提高。例如:头文件的使用,变量和数组的范
15、围问题,定义变量时出现的问题等等。在实际的上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次实习可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。在这次短短的课程实践里,我们得到了卢鹏丽老师的关心和帮助。她给了我们很多的信息,与我们一起探讨问题,询问我们遇到了哪些问题并耐心给予指导。当我们遇到技术上难以解决的问题时,她就会指导我们解决问题,她把自己多年来积累的经验教授给我们,使我们顺利地完成了课程实践任务。时间过得真快,大学生活不知不觉就走过了一年,一年的大学学习和课程实践阶段的提高,使我们本身知识得到提高的同时,也增
16、强了我们对未来工作的信心,我们相信自己未来的学习更使我们有能力胜任将来的工作。17参考文献1 严蔚敏,吴伟民.数据结构(C 语言版) .清华大学出版社.2 严蔚敏,吴伟民.数据结构题集(C 语言版) .清华大学出版社.3 DATA STRUCTURE WITH C+. William Ford,William Topp .清华大学出版社(影印版). 4 谭浩强.c 语言程序设计. 清华大学出版社. 5数据结构与算法分析(Java 版) , A Practical Introduction to Data Structures and Algorithm Analysis Java Editio
17、n Clifford A. Shaffer , 张铭,刘晓丹译 电子工业出版社 2001 年 1 月18致 谢在这样的一个程序设计中,靠一个人的单打独斗是不可能完成的。在这次设计过程中,在开始的构思、设想,源代码编写时的提示,上机时精心的指点,有了老师和舍友以及身边同学的指导、意见和帮助,最终才完成了这个迷宫求解问题系统的设计与实现。所以在这里要对以上老师及同学表示感谢,非常感谢他们的帮助。而且在这次课程设计中我学习到了很多很多。19附件 部分源程序代码void main()int i,m,n,cycle=0;while(cycle!=(-1)printf(“*n“); printf(“ 欢迎
18、进入迷宫求解系统n“);printf(“ 设计者: 兰理工计算机 4 班赵永刚 n“);printf(“*n“);printf(“ 手动生成迷宫 请按:1n“);printf(“ 自动生成迷宫 请按:2n“);printf(“ 退出 请按:3nn“);printf(“*n“); printf(“n“);printf(“请选择你的操作:n“);scanf(“%d“,switch(i)case 1:printf(“n 请输入行数:“);scanf(“%d“,printf(“n“);printf(“请输入列数:“);scanf(“%d“,while(m39)|(n39)printf(“n 抱歉,你输
19、入的行列数超出预设范围(0-39,0-39), 请重新输入:nn“);printf(“请输入行数:“);scanf(“%d“,20printf(“n“);printf(“请输入列数:“);scanf(“%d“,shoudong_maze(m,n);print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n);printf(“nnPress Enter Contiue!n“);getchar();while(getchar()!=n);break;case 2:printf(“n 请输入行数:“);scanf(“%d“,printf(“n“
20、);printf(“请输入列数:“);scanf(“%d“,while(m39)|(n39)printf(“n 抱歉,你输入的行列数超出预设范围(0-39,0-39), 请重新输入:nn“);printf(“请输入行数:“);scanf(“%d“,printf(“n“);printf(“请输入列数:“);scanf(“%d“,zidong_maze(m,n);print_maze(m,n);mgpath(maze,m,n);if(X!=0) result_maze(m,n);printf(“nnPress Enter Contiue!n“);getchar();while(getchar()!=n);break;case 3:cycle=(-1);break;default:printf(“n“);printf(“你的输入有误!n“);printf(“nPress Enter Contiue!n“);getchar();while(getchar()!=n);break;21