上篇博客对多通路迷宫进行求解,现在我们对简单迷宫(只有一条通路)进行求解,用两种方式找到迷宫路径------>循环和递归;
下面使用C语言实现对简单迷宫求解:
maze.c
#define _CRT_SECURE_NO_WARNINGS 0;
#include "maze.h"
#include "stack.h"
#include <stdio.h>
#include <assert.h>
//初始化迷宫
void MazeInit(maze* s, DataTypeMaze arr[MAZE_ROW][MAZE_COL])
{
assert(s);
int i = 0, j = 0;
for (i = 0; i < MAZE_ROW; i++)
{
for (j = 0; j < MAZE_COL; j++)
{
s->maze[i][j] = arr[i][j];
}
}
}
//打印迷宫
void PrintMaze(maze m)
{
int i = 0, j = 0;
for (i = 0; i < MAZE_ROW; i++)
{
for (j = 0; j < MAZE_COL; j++)
{
printf("%d ", m.maze[i][j]);
}
printf("\n");
}
}
// 检测迷宫的入口是否有效
int IsValidEnter(maze *m, PosType enter)
{
assert(m);
if ((enter._x == 0) || (enter._y == 0) || (enter._x == MAZE_ROW - 1) || (enter._y == MAZE_COL - 1))
{
if (m->maze[enter._x][enter._y] >= 1)
return 1;
}
return 0;
}
// 检测cur位置是否为迷宫的出口
int IsMazeExit(maze* m, PosType cur, PosType enter)
{
assert(m);
if (cur._x == enter._x && cur._y == enter._y)
return 0;
if (cur._x == 0 || cur._x == MAZE_COL - 1 || cur._y == 0 || cur._y == MAZE_ROW - 1)
{
return 1;
}
return 0;
}
// 检测当前位置是否为通路
int IsPass(maze* m, PosType cur)
{
assert(m);
if (m->maze[cur._x][cur._y] == 1)
return 1;
return 0;
}
// 打印路径
void PrintPath(Stack* s)
{
assert(s);
printf("over");
while (!IsEmptyStack(s))
{
printf("<- %d,%d ", StackTop(s));
StackPop(s);
}
}
下面是用循环实现的求解:
// 走迷宫 -->循环方式
void PassMazeNor(maze* m, PosType enter, Stack* s)
{
assert(m);
assert(s);
PosType next = enter;
PosType cur = enter;
if (!IsValidEnter(m, enter))
{
printf("无效的入口!!!\n");
return;
}
StackPush(s, enter);
while (!IsEmptyStack(s))
{
cur = StackTop(s);
m->maze[cur._x][cur._y] = 2;
if (IsMazeExit(m, cur, enter))
return;
//上
next = cur;
next._x -= 1;
if (IsPass(m, next))
{
StackPush(s, next);
continue;
}
//右
next = cur;
next._y+= 1;
if (IsPass(m, next))
{
StackPush(s, next);
continue;
}
//左
next = cur;
next._y-= 1;
if (IsPass(m, next))
{
StackPush(s, next);
continue;
}
//下
next = cur;
next._x += 1;
if (IsPass(m, next))
{
StackPush(s, next);
continue;
}
StackPop(s);
}
}
下面是用递归实现的求解:
// 走迷宫
void PassMaze(maze* m, PosType enter)
{
assert(m);
Stack s;
if (!IsValidEnter(m, enter))
{
printf("无效的入口!!!\n");
return 0;
}
StackInit(&s);
_PassMaze(m, enter, enter);
}
// 真正走迷宫的操作 -->递归
int _PassMaze(maze* m, PosType enter, PosType cur)
{
assert(m);
PosType next = cur;
if (IsPass(m, cur))
{
m->maze[cur._x][cur._y] = 2;
if (IsMazeExit(m, cur, enter))
return 1;
//上
next = cur;
next._x -= 1;
if (_PassMaze(m, enter, next))
return 1;
//右
next = cur;
next._y += 1;
if (_PassMaze(m, enter, next))
return 1;
//左
next = cur;
next._y -= 1;
if (_PassMaze(m, enter, next))
return 1;
//下
next = cur;
next._x += 1;
if (_PassMaze(m, enter, next))
return 1;
m->maze[cur._x][cur._y] = 3;
}
return 0;
}
下面是测试代码:
void testMaze()
{
maze m;
Stack s;
PosType enter;
StackInit(&s);
int arr[MAZE_COL][MAZE_ROW] = { { 0 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 1, 1 }, { 0, 0, 1 } };
enter._x = 5;
enter._y = 2;
MazeInit(&m, arr);
PrintMaze(m);
printf("简单迷宫--》递归求解\n");
PassMaze(&m, enter);
PrintMaze(m);
printf("简单迷宫--》循环求解\n");
PassMazeNor(&m, enter, &s);
PrintPath(&s);
}