利用回溯法不断试探且及时纠正错误的方法来求解迷宫问题。从入口出发,按某一方向向前探索,若能走通并且未走过,即该处可以到达,则到达新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回最后一次到达的点,换一个方向继续试探,直到找到一条通路,或无路可走又返回入口点。
定义一个二维数组保存迷宫,1代表墙,0代表通路。定义一个结构体数组pos[MaxSize]存放xy坐标和移动方向dir,dir分别取值0,1,2,3代表上右下左。定义栈顶指针top。
传入起点和终点坐标。思路为:当前位置为起点,起点入栈,以top>-1开始循环,将栈顶元素设为当前位置并将当前位置的mg数组值改为-1表示已经走过了,从当前位置开始按顺序寻找其周围可走路径(数组值0的位置),若找到则将该位置入栈,然后继续循环,然后继续从当前位置周围寻找周围可走路径,若四个方向都没有可走位置则退栈top--并将当前位置,然后当前位置改为上一个走过的位置
-
当前位置为起点,起点入栈
-
while(top>-1),将栈顶元素设为当前位置(i,j)并将当前位置的mg数组值(mg[i][j])改为-1表示已经走过了
-
从当前位置开始按顺序寻找其周围可走路径(数组值0的位置),若找到则将该位置入栈,top++;并返回 第2步 。否则周围没有可走路径进入第4步
-
若没有可走路径则退栈,top--,再返回第2步。
#include <stdio.h>
#define MaxSize 100
//定义一个迷宫,0表示通道,1表示墙
int mg[10][10] ={
{1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,1,1,1},
{1,1,1,0,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,1,1},
{1,1,1,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,0,1},
{1,1,1,1,1,1,1,1,1,1}};
//定义结构体存放位置信息
struct position{
int i;//x坐标
int j;//y坐标
int dir;//方向,0、1、2、3分别代表上,右,下,左
}pos[MaxSize];
//栈顶指针
int top=-1;
//传入起点和终点
void search(int x1, int y1, int x2, int y2)
{
int i,j,dir,find=0;
top++;
pos[top].i=x1;
pos[top].j=y1;
pos[top].dir=-1;
mg[x1][y1]=-1;
while(top>-1)
{
i=pos[top].i;
j=pos[top].j;
dir=pos[top].dir;
if((i==x2)&&(j==y2))//找到迷宫出口,打印栈中的值即可
{
printf("找到迷宫出口!\n");
for(int p=0;p<=top;p++)
{
printf("i=%d,j=%d\n",pos[p].i,pos[p].j);
}
}
find=0;
while(dir<4&&find==0)
{
dir++;
switch(dir)
{
case 0:
i=pos[top].i-1;
j=pos[top].j;
break;
case 1:
i=pos[top].i;
j=pos[top].j+1;
break;
case 2:
i=pos[top].i+1;
j=pos[top].j;
break;
case 3:
i=pos[top].i;
j=pos[top].j-1;
break;
}
if(mg[i][j]==0)
find=1;
}
if(find==1)//如果有路
{
pos[top].dir=dir;
top++;
pos[top].i=i;
pos[top].j=j;
pos[top].dir=-1;
mg[i][j]=-1;//将前一块设置为不能走防止死循环
}
else
{
top--;
i=pos[top].i;
j=pos[top].j;
dir=-1;
}
}
}
int main()
{
//传入起点和终点
search(1,1,8,8);
}