最近在学习C语言的一些经典算法,其中遇到了一点困难,导致卡进度了。琢磨了很久,在绘制流程图时,突然灵感大开理解了,老鼠走迷宫算法的奇妙。所以写了这个,一来是方便以后右和我类似的同学自学时,遇到这个问题可以找到解决的方法,二来是为了记录一下自己的思路,以免以后记不住。俗话说得好,好记性不如烂笔头。
那么废话不多说,进入正题。关于C语言老鼠走迷宫算法,网上有很多案例,CSDN上面也有很多。大家都是能找到的。基本上的思路都是利用数组模拟迷宫,利用函数的递归算法来实现的。
以下为老鼠走迷宫(单路径)的代码:
# include <stdio.h>
# include <Stdlib.h>
int vis(int, int);
int maze[7][7] = {{2, 2, 2, 2, 2, 2, 2},//绘制一个7x7的迷宫
{2, 0, 0, 0, 0, 0, 2},
{2, 0, 2, 0, 2, 0, 2},
{2, 0, 0, 2, 0, 2, 2},
{2, 2, 0, 2, 0, 2, 2},
{2, 0, 0, 0, 0, 0, 2},
{2, 2, 2, 2, 2, 2, 2}};
int startI = 1, startJ = 1;//定义起点
int endI = 5, endJ = 5;//定义终点
int success = 0;//定义终点变量
int main (){
int i, j;
//显示迷宫
printf("显示迷宫: \n");
for(i = 0; i < 7; i++){
for(j = 0; j < 7; j++){
if(maze[i][j] == 2)//当数组内元素为2时就是墙
printf("■ ");
else printf("□ ");//否则就说明其余是路
}
printf("\n");
}
if(vis(startI, startJ) == 0)//调用走迷宫函数vis,寻找从起点到终点的路径,若无法到达此处输出
printf("\n没有找到出口!!! \n");
else {
//输出解密后的路径
printf("\n迷宫路径为:\n");
for(i = 0; i < 7; i++){
for(j = 0; j < 7; j++){
if(maze[i][j] == 2)//同上,2代表墙
printf("■ ");
else if(maze[i][j] == 1)//在29行处调用vis函数后,就已经将迷宫的路径解答出来了. 1代表所走的路径及迷宫正确走法
printf(" ");
else printf("□ ");//否则就是不正确的路
}
printf("\n");
}
}
return 0;
}
int vis(int i, int j){//迷宫解密函数
maze[i][j] = 1;//将当前位置定义为1
if(i == endI && j == endJ) success = 1;//若到达终点,令终点为1
if(success != 1 && maze[i][j+1] == 0) vis(i, j+1);//向右探索路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i+1][j] == 0) vis(i+1, j);//向下探寻路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i][j-1] == 0) vis(i, j-1);//向左探索路径,可以就执行,不行就执行下一条语句
if(success != 1) maze[i][j] = 0;//判断是否到达终点,没有就将路径清零
return success;
}
备注之类的我都写好了。如果你这是想实现一个过程,恭喜你已经完成了,这个代码,是一个7X7的迷宫,如果你有其他的要求那么将数组长度,数组元素以及循环的长度更改一下就行了。
----------------------------------------------------------------------------------------
接下来就是关于算法的详细讲解了,先贴一张算法的流程图:
只要对于C语言有所了解的就应该能够理解,主要就是三部分,初始化,判断,输出。
这里在判断语句中调用了解密函数。也可以单独调用一次解密函数,再判断是否有迷宫的解法。都是可以的。
这个老鼠走迷宫算法的关键就在于解密函数。以下将就解密函数的一部分进行讲解。其他的都是类似的推导方法,以此类推即可。
maze[i][j] = 1;//将当前位置定义为1
if(i == endI && j == endJ) success = 1;//若到达终点,令终点为1
if(success != 1 && maze[i][j+1] == 0) vis(i, j+1);//向右探索路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i+1][j] == 0) vis(i+1, j);//向下探寻路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i][j-1] == 0) vis(i, j-1);//向左探索路径,可以就执行,不行就执行下一条语句
if(success != 1) maze[i][j] = 0;//判断是否到达终点,没有就将路径清零
return success;
由解密函数可知,每次调用解密函数都是将当前的位置赋值为1(就相当于在此处留下了自己的脚印),然后依次判断是否到达终点,若到达终点就令终点变量为 1, 同时返回终点变量值,用于之前的判断; 是否能够向右走,是否能够向下走,是否能够向左走。当依次判断最终找到了终点,那么就会将终点变量返回回去。若之前的探索路径是错误的,就会将当前脚印清除,返回到之前的判断处,尝试其他路径是否能够到达终点,若还是无法到达终点。就再次清除脚印,再返回到之前的判断处尝试其他路径。此处的流程图只是画了一个2次内嵌套。当然代码实现的嵌套数由实际情况而视。
-----------------------------------------------------------------------------------------------------------
这是一个可视化的老鼠尝试各种路径的情况,可以更方便的让大家理解老鼠尝试路径,以及返回的现象。当然,你也可以将迷宫的路径进行更改。
# include <stdio.h>
# include <Stdlib.h>
int vis(int, int);
void pin();
int maze[7][7] = {{2, 2, 2, 2, 2, 2, 2},//绘制一个7x7的迷宫
{2, 0, 0, 0, 0, 0, 2},
{2, 0, 2, 0, 2, 0, 2},
{2, 0, 0, 2, 0, 2, 2},
{2, 2, 0, 2, 0, 2, 2},
{2, 0, 0, 0, 0, 0, 2},
{2, 2, 2, 2, 2, 2, 2}};
int startI = 1, startJ = 1;//定义起点
int endI = 5, endJ = 5;//定义终点
int success = 0;//定义路径变量
int main (){
int i, j;
//显示迷宫
pin();
if(vis(startI, startJ) == 0)//调用走迷宫函数vis,寻找从起点到终点的路径,若无法到达此处输出
printf("\n没有找到出口!!! \n");
else pin();
return 0;
}
int vis(int i, int j){//迷宫解密函数
maze[i][j] = 1;//将当前位置定义为1
pin();
if(i == endI && j == endJ) success = 1;//若到达终点,令终点为1
if(success != 1 && maze[i][j+1] == 0) vis(i, j+1);//向右探索路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i+1][j] == 0) vis(i+1, j);//向下探寻路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i][j-1] == 0) vis(i, j-1);//向左探索路径,可以就执行,不行就执行下一条语句
if(success != 1 && maze[i-1][j] == 0) vis(i-1, j);//向上返回,
if(success != 1) {maze[i][j] = 0; pin();}//判断是否到达终点,没有就将路径清零
return success;
}
void pin(){
printf("\n迷宫路径为:\n");
int i, j;
for(i = 0; i < 7; i++){
for(j = 0; j < 7; j++){
if(maze[i][j] == 2)
printf("■ ");
else if(maze[i][j] == 1)//在29行处调用vis函数后,就已经将迷宫的路径解答出来了,并将所走路径设置为1
printf("→ ");
else printf("□ ");
}
printf("\n");
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)