摘 要
迷宫最早出现在古希腊神话中。
据说,半人半神的英雄西修斯 (Theseus) 在克里特的迷宫中勇敢地杀死半人半牛的怪物,并循着绳索 (Ariadne 抓住另一头 ) 逃出迷宫。 希腊史学家希罗多德曾探访过那里。他描述说,整个迷宫由 12 座带顶院落构成,所有院落都由通道连接,形成 3000 个独立的“室”。据说,建造这座迷宫用的人力和财力“超过了希腊所有的建筑”。后来的参观者也说,一旦进入迷宫,如果没向导,根本无望走出。若不是知情人泄露了地图,盗墓者可能永远也无法探明克里特迷宫。
现在,在人们的生活中,迷宫随处可见,它在各个领域被广泛应用。本程序就是利用C语言知识和数据结构算法所做成的简易迷宫。
关键词:迷宫 C语言 数据结构
第一章 绪 论
1.1 课设主要研究问题
二维数组本质上是以数组作为数组元素的数组,即"数组的数组",类型说明符 数组名[常量表达式][常量表达式]。二维数组又称为矩阵,行列数相等的矩阵称为方阵。对称矩阵a[i][j] = a[j][i],对角矩阵:n阶方阵主对角线外都是零元素。
递归是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象。在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知。
使用递归解决问题,思路清晰,代码少。但是在主流高级语言中(如C语言、Pascal语言等)使用递归算法要耗用更多的栈空间,所以在堆栈尺寸受限制时(如嵌入式系统或者内核态编程),应避免采用。所有的递归算法都可以改写成与之等价的非递归算法。
二维数组A[m][n],这是一个m行,n列的二维数组。设a[p][q]为A的第一个元素,即二维数组的行下标从p到m+p,列下标从q到n+q,按"行优先顺序"存储时则元素a[i][j]的地址,按"列优先顺序"存储时的地址。存放该数组至少需要的单元数为(m-p+1) * (n-q+1) * t 个字节。递归,就是在运行的过程中调用自己。而构成递归需具备的条件以函数嵌套调用过程示例:1. 子问题须与原始问题为同样的事,且更为简单;2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。在数学和计算机科学中,递归指由一种(或多种)简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为其基本情况。
2.2 实现具体过程
Maze方法写入迷宫实现创建:
int createMaze();
int createFreeMaze();
void createWall();
int visit(int row2, int col2) ;
int startI = 1, startJ = 1;
int success = 0;
int maze[100][100];
int row = 0;
int col = 0;
//迷宫矩阵,2代表墙壁,0代表通道
void createWall()
{
for(int i = 0; i < col; i++)//行
maze[0][i] = 2;
for(int i = 1; i < row; i++)//列
maze[i][0] = 2;
for(int i = 1; i < col; i++)//最后一行
maze[row-1][i] = 2;
for(int i = 1; i < row-1; i++)//最后一列
maze[i][col-1] = 2;
递归方法调用函数(四个方向):
int visit(int row2, int col2)
{
int endI = row-2, endJ = col-2;
maze[row2][col2] = 1;
if(row2 == endI && col2 == endJ)
success = 1;
if(success != 1 && maze[row2][col2+1] == 0)
visit(row2, col2+1);
if(success != 1 && maze[row2+1][col2] == 0)
visit(row2+1, col2);
if(success != 1 && maze[row2][col2-1] == 0)
visit(row2, col2-1);
if(success != 1 && maze[row2-1][col2] == 0)
visit(row2-1, col2);
if(success != 1)
maze[row2][col2] = 0;
return success;
}
显示迷宫的界面:
int main(void)
{
int i, j;
printf("请输入迷宫行数row(0<row<100):");
scanf("%d",&row);
printf("请输入迷宫列数col(0<col<100):");
scanf("%d",&col);
createWall();//创建迷宫外墙
int choice;
printf("请选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫):");
scanf("%d",&choice);
if(choice == 1)
{
createMaze(); //创建迷宫
}
else if(choice == 2)
{
printf("\n请输入自定义迷宫的墙壁和通道,2代表墙壁,0代表通道\n");
createFreeMaze();
}
printf("\n显示迷宫:\n");
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if(maze[i][j] == 2)
printf("█");
else
printf(" ");
}
printf("\n");
}
if(visit(startI, startJ) == 0)
{
printf("\n没有找到出口!\n");
}
else
{
printf("\n显示路径:\n");
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if(maze[i][j] == 2)
printf("█");
else if(maze[i][j] == 1)
printf("◇");
else
printf(" ");
}
printf("\n");
}
}
system("pause");
return 0;
}
2.3 实现结果
用户首先根据提示输入迷宫行数列数,再选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫)。
如果创建随机迷宫输入1,接下来程序会自动创建随机迷宫,并对迷宫进行寻找出口操作,有出口则显示含有出口路径的迷宫图,没有出口则显示:没有找到出口!
如果创建自定义迷宫,则根据提示输入代表墙壁的2或者代表通道的0组成迷宫,
有出口则显示含有出口路径的迷宫图,没有出口则显示:没有找到出口!
1、有出口的自定义迷宫
2、没有出口的随机迷宫
3、有出口的随机迷宫
程序代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int createMaze(); //创建随机迷宫
int createFreeMaze(); //创建自定义迷宫
void createWall(); //创建迷宫外墙
int visit(int row2, int col2) ;
int startI = 1, startJ = 1; // 入口
int success = 0;
//迷宫数组
int maze[100][100];
int row = 0;
int col = 0;
//迷宫矩阵,2代表墙壁,0代表通道
//创建迷宫外墙
void createWall()
{
//创建迷宫外墙,第一行、第一列、最后一行、最后一列均为墙壁
for(int i = 0; i < col; i++)//第一行
maze[0][i] = 2;
for(int i = 1; i < row; i++)//第一列
maze[i][0] = 2;
for(int i = 1; i < col; i++)//最后一行
maze[row-1][i] = 2;
for(int i = 1; i < row-1; i++)//最后一列
maze[i][col-1] = 2;
}
//创建随机迷宫
int createMaze()
{
srand(time(0));
for(int i = 1; i < row-1; i++)
{
for(int j = 1; j < col-1; j++)
{
if((rand()%100+1) % 2 == 0)
maze[i][j] = 0;
else
maze[i][j] = 2;
}
}
maze[1][1] = 0;
maze[row-2][col-2] = 0;
}
//创建自定义迷宫
int createFreeMaze()
{
for(int i = 1; i < row-1; i++)
{
//第一行,第一格为入口
if(i == 1)
{
printf("迷宫第%d行,共%d格: ",i,col-3);
for(int j = 2; j < col-1; j++)
scanf("%d",&maze[i][j]);
}
//最后一行,最后一格为出口
else if(i == row-2)
{
printf("迷宫第%d行,共%d格:",i,col-3);
for(int j = 1; j < col-2; j++)
scanf("%d",&maze[i][j]);
}
else
{
printf("迷宫第%d行,共%d格:",i,col-2);
for(int j = 1; j < col-1; j++)
scanf("%d",&maze[i][j]);
}
}
maze[1][1] = 0; //入口为通道
maze[row-2][col-2] = 0; //出口为通道
}
int visit(int row2, int col2)
{
int endI = row-2, endJ = col-2; // 出口
//该点走过,标记为1
maze[row2][col2] = 1;
//走到终点,成功
if(row2 == endI && col2 == endJ)
success = 1;
//向四个方向递归调用函数visit()
if(success != 1 && maze[row2][col2+1] == 0)
visit(row2, col2+1);
if(success != 1 && maze[row2+1][col2] == 0)
visit(row2+1, col2);
if(success != 1 && maze[row2][col2-1] == 0)
visit(row2, col2-1);
if(success != 1 && maze[row2-1][col2] == 0)
visit(row2-1, col2);
//该点走过,但没成功,则该点重新置为0
if(success != 1)
maze[row2][col2] = 0;
return success;
}
int main(void)
{
int i, j;
printf("请输入迷宫行数row(0<row<100):");
scanf("%d",&row);
printf("请输入迷宫列数col(0<col<100):");
scanf("%d",&col);
createWall();//创建迷宫外墙
int choice;
printf("请选择创建随机迷宫还是自定义迷宫(1为随机迷宫,2为自定义迷宫):");
scanf("%d",&choice);
if(choice == 1)
{
createMaze(); //创建迷宫
}
else if(choice == 2)
{
printf("\n请输入自定义迷宫的墙壁和通道,2代表墙壁,0代表通道\n");
createFreeMaze();
}
printf("\n显示迷宫:\n");
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if(maze[i][j] == 2)
printf("█");
else
printf(" ");
}
printf("\n");
}
if(visit(startI, startJ) == 0)
{
printf("\n没有找到出口!\n");
}
else
{
printf("\n显示路径:\n");
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
if(maze[i][j] == 2)
printf("█");
else if(maze[i][j] == 1)
printf("◇");
else
printf(" ");
}
printf("\n");
}
}
system("pause");
return 0;
}