迷宫求解
- 核心代码解析
栈中存放的数据可以理解为上一个可以通行的格子,因为在递归的时候当一个格子遇到能通行的方向的时候就不再尝试其他方向了,所以当一个格子弹出的时候,就意味着回到了弹出的这个坐标上边。
bool findPath(Maze* maze, ArrList pArr)
{
direct[0].incX = 0;
direct[0].incY = 1;
direct[1].incX = 1;
direct[1].incY = 0;
direct[2].incX = 0;
direct[2].incY = -1;
direct[3].incX = -1;
direct[3].incY = 0;
Box temp;
int x, y, di;//存放当前的坐标和方向
int line, col;//存放下一个能移动的坐标和方向
maze->map[1][1] = -1;//首先把第一个点置-1放入栈中
temp.x = 1;
temp.y = 1;
temp.di = -1;//这里让第一次时候方向为-1方便在迭代过程中+1的操作
push(pArr,temp);
while (!is_empty(pArr))//当栈里存放不为空的时候进行迭代
{
temp = pop(pArr);
x = temp.x;
y = temp.y;
di = temp.di+1;
while (di < 4)
{
line = x + direct[di].incX;//这里是下一个将要移动的点。
col = y + direct[di].incY;
if (maze->map[line][col] == 0)
{
temp.x = x;
temp.y = y;
temp.di = di;
push(pArr, temp);//将能通行的通道压入栈中
x = line;//存入下一个点的信息
y = col;
maze->map[line][col] = -1;
if (x == 4 && y == 4)//检查是否到达终点
return true;
else
di = 0;
}
else
di++;//四种方向
}
}
return false;
}
- 源代码
注意:这里自己手写栈一定要注意数据类型,可以使用c++或者java里面现成的数据结构。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int incX, incY;
}Direction;
typedef struct Maze {
int map[10][10];//为了方便我们对地图的控制,这里设置两个全局的行、列
}Maze;
typedef struct
{
int x, y;
int di;
}Box;
typedef struct arr
{
Box* pBase;
int len;
int top;
}Arr,*ArrList;
Direction direct[4]{};
ArrList init_Arr(int length)
{
ArrList pArr = (ArrList)malloc(sizeof(Arr));
pArr->pBase = (Box*)malloc(sizeof(Box)*length);
pArr->len = length;
pArr->top = 0;
return pArr;
}
bool is_empty(ArrList pArr)
{
if (pArr->top==0)
return true;
else
return false;
}
bool is_full(ArrList pArr)
{
if (pArr->len == pArr->top)
return true;
else
return false;
}
void push(ArrList pArr,Box val)
{
if (is_full(pArr))
{
printf("栈满了");
exit(-1);
}
else
{
pArr->pBase[pArr->top] = val;
pArr->top++;
}
}
Box pop(ArrList pArr)
{
Box val;
if (is_empty(pArr))
{
printf("栈空了");
exit(-1);
}
else
{
val = pArr->pBase[pArr->top-1];
pArr->top--;
}
return val;
}
void show(ArrList pArr)
{
for (int i = 0; i < pArr->top; ++i)
{
printf("所处位置为(%d,%d),方向为%d\n",pArr->pBase[i].x,pArr->pBase[i].y,pArr->pBase[i].di);
}
}
Maze* create_maze()
{
Maze* maze = (Maze*)malloc(sizeof(Maze));
int map[6][6] = {
{1,1,1,1,1,1},
{1,0,0,0,0,1},
{1,1,0,1,1,1},
{1,1,0,0,1,1},
{1,0,0,0,0,1},
{1,1,1,1,1,1}
};
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
maze->map[i][j] = map[i][j];
}
}
return maze;
}
bool findPath(Maze* maze, ArrList pArr)
{
direct[0].incX = 0;
direct[0].incY = 1;
direct[1].incX = 1;
direct[1].incY = 0;
direct[2].incX = 0;
direct[2].incY = -1;
direct[3].incX = -1;
direct[3].incY = 0;
Box temp;
int x, y, di;
int line, col;
maze->map[1][1] = -1;
temp.x = 1;
temp.y = 1;
temp.di = -1;
push(pArr,temp);
while (!is_empty(pArr))
{
temp = pop(pArr);
x = temp.x;
y = temp.y;
di = temp.di+1;
while (di < 4)
{
line = x + direct[di].incX;
col = y + direct[di].incY;
if (maze->map[line][col] == 0)
{
temp.x = x;
temp.y = y;
temp.di = di;
push(pArr, temp);
x = line;
y = col;
maze->map[line][col] = -1;
if (x == 4 && y == 4)
return true;
else
di = 0;
}
else
di++;
}
}
return false;
}
int main()
{
ArrList pArr = init_Arr(20);
Maze* maze = create_maze();
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
printf("%d", maze->map[i][j]);
if (j == 5)
printf("\n");
}
}
if (findPath(maze, pArr))
printf("迷宫有解\n");
else
printf("迷宫没有解\n");
printf("通关路径为:(右(0)下(1)左(2)上(3))");
show(pArr);
}
- 结果