如图迷宫,求解带环迷宫的出口
- 同样利用递归求解,不同的是没走一步,要标记成上一步大1的值
- 当到达出口后,更新最短路径,然后回退,找别的方向的路线,在回退时,碰到标记数值比自己大的是走不通的。
思路
找到一条路径后,然后找第二条
代码如下
Maze.h
#include "SqStack.h"
#define MAX_ROW 4
#define MAX_COL 4
typedef struct Maze
{
int _map[MAX_ROW][MAX_COL];
}Maze, *PMaze;
// 栈的初始化
void InitMaze(PMaze m, int map[][MAX_COL]);
// 检测入口是否为有效入口
int IsValidEntry(PMaze m, Position entry);
// 检测cur位置是否是通路
int IsPass(PMaze m, Position cur);
// 检测pcur是否在出口
int IsExit(PMaze m, Position cur, Position entry);
// 走迷宫
void PassMaze(PMaze m, Position entry, PSqStack s);
// 打印迷宫
void PrintMaze(PMaze m);
//检测路径边界是否合法
int IsValidPath(PMaze m, Position cur, Position next);
//更新最短路径
void UpdatePath(PSqStack path, PSqStack shortpath);
void TestMaze();
##### Maze.c
#include "Maze.h"
// 迷宫的初始化
void InitMaze(PMaze m, int map[][MAX_COL])
{
int i = 0;
int j = 0;
assert(m);
for (i = 0; i < MAX_ROW; ++i)
{
for (j = 0; j < MAX_COL; ++j)
{
m->_map[i][j] = map[i][j];
}
}
}
//打印迷宫
void PrintMaze(PMaze m)
{
assert(m);
for (int i = 0; i < MAX_ROW; ++i)
{
for (int j = 0; j < MAX_COL; ++j)
{
printf("%d ", m->_map[i][j]);
}
putchar('\n');
}
printf("\n\n");
}
// 检测pcur是否在出口
int IsExit(PMaze m, Position cur, Position entry)
{
//出口在边界且不能和入口重合
if ((cur._x == 0 || cur._x == MAX_ROW - 1 ||
cur._y == 0 || cur._y == MAX_COL - 1) &&
(cur._x != entry._x) && (cur._y != entry._y)
)
{
return 1;
}
return 0;
}
// 检测入口是否为有效入口
int IsValidEntry(PMaze m , Position entry)
{
assert(m);
//入口在边界,且值为1
if ((entry._x == 0 || entry._x == MAX_ROW - 1 ||
entry._y == 0 || entry._y == MAX_COL - 1) &&
(m->_map[entry._x][entry._y]==1))
{
return 1;
}
return 0;
}
//更新最短路径
void UpdatePath(PSqStack path, PSqStack shortpath)
{
int i = 0;
int size = path->_size;
for (i = 0; i < size; ++i)
{
shortpath->_array[i] = path->_array[i];
}
shortpath->_size = i;
}
//检测路径边界是否合法
int IsValidPath(PMaze m, Position cur, Position next)
{
//next值不能越界
if (next._x < 0 || next._x >= MAX_ROW ||
next._y < 0 || next._y >= MAX_COL)
{
return 0;
}
//next值为1,且next值大于cur值
else if (m->_map[next._x][next._y] == 1 ||
(m->_map[cur._x][cur._y]< m->_map[next._x][next._y]))
{
return 1;
}
return 0;
}
void _PassMazeLoop(PMaze m, Position cur,Position entry, PSqStack path, PSqStack shortpath)
{
Position next;
SqStackPush(path, cur);
if (IsExit(m, cur, entry))
{
if ( SqStackEmpty(shortpath) || (path->_size < shortpath->_size))
{
UpdatePath(path, shortpath);
}
SqStackPop(path);
return;
}
//up
next = cur;
next._x -= 1;
if (IsValidPath(m, cur, next))
{
m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
_PassMazeLoop(m, next, entry, path, shortpath);
}
//left
next = cur;
next._y -= 1;
if (IsValidPath(m, cur, next))
{
m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
_PassMazeLoop(m, next, entry, path, shortpath);
}
//right
next = cur;
next._y += 1;
if (IsValidPath(m, cur, next))
{
m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
_PassMazeLoop(m, next, entry, path, shortpath);
}
//down
next = cur;
next._x += 1;
if (IsValidPath(m, cur, next))
{
m->_map[next._x][next._y] = m->_map[cur._x][cur._y] + 1;
_PassMazeLoop(m, next, entry, path, shortpath);
}
//四个方向都不通
SqStackPop(path);
return;
}
void PassMazeLoop(PMaze m, Position entry, PSqStack path,PSqStack shortpath)
{
if (!IsValidEntry(m, entry))
{
printf("入口不合法!\n");
return;
}
m->_map[entry._x][entry._y] = 2;
_PassMazeLoop(m, entry, entry, path, shortpath);
}
void TestMaze()
{
// SqStack s;
Maze m;
Position entry;
int map[4][4] = {{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 0 }};
//SqStackInit(&s);
SqStack path;
SqStack shortpath;
SqStackInit(&path);
SqStackInit(&shortpath);
InitMaze(&m, map);
PrintMaze(&m);
entry._x = 3;
entry._y = 1;
PassMazeLoop(&m, entry, &path, &shortpath);
PrintMaze(&m);
printf("出口路径: ");
SqStackPrint(&shortpath);
//SqStackPrint(&path);
}