《数据结构实践》设计报告—迷宫求解
因为学校要求答辩结课,给了很多题目都不太会,决定把感兴趣的都做一做,在这存档备用。
课程设计题目:迷宫求解
课程设计主要内容和要求:
一.设计目的:
1.掌握栈的特点及其描述方法
2.掌握链栈的各种基本操作
二.设计内容和要求:
由0和1构成的m*n维矩阵表示一个迷宫,其中0表示通路,1表示墙壁。迷宫入口为(1,0),出口为(m-1,n)。迷宫随机产生。试编一算法求出从入口到出口的一条通路,或显示没有通路。要求实现如下功能:
1.从键盘输入m和n,随机产生迷宫。
2.找到一条通路即可,若没有显示“No path!”。
--------------------------------------------------------------------
一、题目描述
以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
二、解题思路
建立一个迷宫:
1、先建立一个数组假设数组存储的全为墙(wall),假设迷宫只有一条正确的道路。
2、确定迷宫的起点(route),以起点为根节点向下搜索,搜索到墙(wall),将墙变为路(route)。
3、我们挖的道路就像树结构,树上有很多的分支,分支也有子分支,每个子分支都不能相交,相交就说明墙被推倒了,那么此时的迷宫就可能存在多条正确道路,那么基于唯一道路的原则,我们向某个方向搜索一块新的区域时,要先判断新区域是否有形成回路的可能,如果可能要立即停止并换个方向搜索。
4、因为采用了递归的方式,所以给迷宫外层围上墙之后,再在墙外围上一条路。避免程序永久执行下去。
寻找迷宫路径:
1、 将迷宫起点压栈,标记已走过道路。
2、 向四个方向遍历,寻找是路的邻接点。
3、 确认邻接点可行将邻接点压栈,标记邻接点为可行路径。如果邻接点不可行,则将邻接点弹栈。
4、 重复,遍历到出口节点,输出路径。
5、 如栈空,输出No path!
三、主要数据结构
1、使用数组存储迷宫,方便好看。使用静态二维数组作为参数传递比较麻烦,一般需要指明第二维的长度,但在本题情况中,第二维长度未知。所以使用malloc内存动态分配数组,既保证数组连续性,又方便传递参数。
int **Maze = (int**)malloc(M * sizeof(int *));
for(i=0;i<M;i++){
Maze[i]=(int*)malloc(N * sizeof(int));
}
2、使用栈存储迷宫路径,因为栈的原则是先进后出,符合迷宫走错路就退一步的特点。栈使用链式存储方式,用于存放遍历的点和下一个点运动的方向。
struct MG{
int i;
int j;
int di; ///记录方向
}Stack[MaxSize];///栈:存放路径
四、相关算法介绍
深度优先搜索:目的是要达到被搜索结构的叶结点。即在搜索其余的结果之前必须先完整地搜索单独的一条链。深度优先搜索沿着结点走到不能再深入为止,然后返回到某一个结点,再继续选择其他结点搜索。当不再有其他结点可选择时,说明搜索已经结束。
使用图的深度遍历:
(1)从迷宫起点节点V开始访问
(2)访问这个节点V,标记为可行的路径;
(3)从v的未被访问的非"墙"邻接点中选取一个顶点w,重复第二步。如果v没有未访问的非"墙"邻接点,把这个节点的可行路径标记移除,回溯至上一节点;
(4)重复上述第(2)、(3)步,直至遍历到迷宫的出口节点。
五、源程序
#include<stdio.h>
#include<time.h>
#include<math.h>
#include <stdlib.h>
///墙和路径的标识
#define wall 0
#define route 1
#define path 3
#define MaxSize 100///规定栈空间最大是100
struct MG{
int i;
int j;
int di; ///记录方向
}Stack[MaxSize];///栈:存放路径
int top=-1;
///声明函数
void CreateMaze(int **maze, int x, int y);
void mgpath(int **maze,int M, int N);
int main() {
srand((unsigned)time(NULL));/***生成随机数***/
int M,N;
printf("请输入迷宫长度M,宽度N(长宽差2,空格间隔)\n");
scanf("%d %d/n",&M,&N);
M=M+2;N=N+2;///加上外侧包围墙体,最外侧包围路径。
int i,j;
int