#回溯算法的经典应用–迷宫寻径
先科普下啥是回溯算法,简单的说就是把一件事的所有可能性都测试一遍,对于初步可行的可能性在进行深度试探,初步就不行的就回到上一层可行的继续试探其他的可行性,直到寻求到所找目的。
最经典的应用,迷宫寻找出口,本例使用递归实现,话就不多说了,上代码。
#include <stdio.h>
//路径图 用 1 模拟围墙,0为可通过的路径
int map[10][10] = {
1,0,1,1,1,1,1,1,0,1,
1,0,1,1,1,1,1,1,0,1,
1,0,1,0,1,1,1,1,0,1,
1,0,1,0,1,1,1,1,0,1,
1,0,1,0,1,1,0,0,0,1,
1,0,1,0,1,1,0,1,1,1,
1,0,1,0,0,0,0,1,1,1,
1,0,1,0,1,1,0,0,1,1,
1,0,0,0,1,1,1,0,0,1,
1,1,1,1,1,1,1,1,1,1,
};
int (*p)[10] = map;
//以x,y为起点开始寻径
int find_path(int x,int y)
{
//参数合法性检测
if(x < 0 || y < 0)
{
return 0;
}
if(x == 0 && y == 8)
{
*(*(p + x) + y) = 6;
return 1;
}
if(*(*(p + x) + y) == 0)
{
//标记走过标志,
*(*(p + x) + y) = 6;
// 判断 上下左右是否有路可走
if(find_path(x - 1,y) || find_path(x + 1,y) || find_path(x , y -1) || find_path(x,y + 1) )
{
//printf("%d,%d\n",x,y);
//标记有效位置
//*(*(p + x) + y) = 6;
return 1;
}
else
{
//标记走过的无效位置
*(*(p + x) + y) = 4;
return 0;
}
}
else
{
return 0;
}
}
void show_path(void)
{
int i,j;
for(i = 0; i < 10; i ++)
{
for(j = 0; j < 10; j ++)
{
printf("%d",*(*(p + i) + j));
}
printf("\n");
}
}
int main()
{
if(find_path(0,1) > 0)
{
printf("找到出口了\n");
show_path();
}
else
{
printf("未找到出口");
}
}
#思路简单介绍:
使用递归的方法,从入口开始尝试周边是否有路可走,直到找到指定的出口。
运行结果:图中标记为6的路径为有效的出口路径,而标记为4的路径则为走过的无效路径,而 标记为0的位置则为未尝试的路径
#问题遗留:
如图所示,函数find_path中,中把状态赋值移到条件判断中后会出现段错误异常,尚未知道原因