如图,一个不带环且只有一条通路的简单迷宫
我们想要解此迷宫,思路如下:
普通求解
- 利用栈结构首先从入口进去,这里要判断入口是否合法,走一步将其标记成2,并且入栈,代表已经走过
我们从该点,一次向上,左,右,下四个方向探索 ,值为 1代表能走通,入栈,如果都走不通,将其标记为3, 退一步,将当前坐标出栈。
代码试下如下
Maze.h
#include "SqStack.h"
#define MAX_ROW 6
#define MAX_COL 6
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);
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) &&
(m->_map[cur._x][cur._y] == 1) &&
(cur._x != entry._x) && (cur._y != entry._y)
)
{
return 1;
}
return 0;
}
// 检测入口是否为有效入口
int IsValidEntry(PMaze m , Position entry)
{
assert(m);
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;
}
// 检测cur位置是否是通路
int IsPass(PMaze m, Position cur)
{
assert(m);
//值为1,不越界
if (1 == m->_map[cur._x][cur._y] &&
(cur._x >= 0 && cur._x < MAX_ROW)&&
(cur._y >= 0 && cur._y < MAX_COL))
{
return 1;
}
return 0;
}
// 走迷宫
void PassMaze(PMaze m, Position entry, PSqStack s)
{
Position cur;
Position next;
assert(m);
assert(s);
if (!IsValidEntry(m, entry))
{
printf("迷宫入口不合法!\n");
return;
}
SqStackPush(s,entry);
while (!SqStackEmpty(s))
{
cur = SqStackTop(s);
if (IsExit(m, cur, entry))
{
m->_map[cur._x][cur._y] = 2;
printf("已经找到出口!\n");
return;
}
m->_map[cur._x][cur._y] = 2;
//up
next = cur;
next._x -= 1;
if (IsPass(m, next))
{
SqStackPush(s, next);
continue;
}
//left
next = cur;
next._y -= 1;
if (IsPass(m, next))
{
SqStackPush(s, next);
continue;
}
//right
next = cur;
next._y += 1;
if (IsPass(m, next))
{
SqStackPush(s, next);
continue;
}
//down
next = cur;
next._x += 1;
if (IsPass(m, next))
{
SqStackPush(s, next);
continue;
}
m->_map[cur._x][cur._y] = 3;
SqStackPop(s);
}
printf("迷宫没有出口!\n");
}
//测试函数
void TestMaze()
{
SqStack s;
Maze m;
Position entry;
int map[6][6] = {{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0 }};
SqStackInit(&s);
InitMaze(&m, map);
PrintMaze(&m);
entry._x = 5;
entry._y = 2;
PassMaze(&m, entry, &s);
PrintMaze(&m);
printf("出口路径: ");
SqStackPrint(&s);
}
SqStack.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
#include <string.h>
#define MAX_SIZE 10
//typedef int DataType;
//typedef char DataType;
typedef struct Position
{
int _x;
int _y;
}Position;
typedef Position DataType;
typedef struct Stack
{
DataType _array[MAX_SIZE];
int _size;
}SqStack, *PSqStack;
void SqStackInit(PSqStack s); //栈的初始化
void SqStackPush(PSqStack s, DataType data); //入栈
void SqStackPop(PSqStack s); //出栈
DataType SqStackTop(PSqStack s); //查看栈顶数据
int SqStackSize(PSqStack s); //查看当前栈里的元素个数
int SqStackEmpty(PSqStack s); //检查栈是否为空
void SqStackPrint(PSqStack s); //打印栈中元素
SqStack.c
#include "SqStack.h"
//栈的初始化
void SqStackInit(PSqStack s)
{
assert(s);
s->_size = 0;
}
//入栈
void SqStackPush(PSqStack s, DataType data)
{
assert(s);
if (10 == s->_size) //栈已满
return;
s->_array[s->_size] = data;
s->_size++;
}
//出栈
void SqStackPop(PSqStack s)
{
assert(s);
if (0 == s->_size)
return;
s->_size--;
}
//查看栈顶数据
DataType SqStackTop(PSqStack s)
{
assert(s);
if (0 == s->_size)
{
printf("栈为空!\n");
return s->_array[s->_size-1];
}
return s->_array[s->_size - 1];
}
//查看当前栈里的元素个数
int SqStackSize(PSqStack s)
{
assert(s);
return s->_size;
}
//检查栈是否为空
int SqStackEmpty(PSqStack s)
{
if (0 == s->_size)
return 1;
return 0;
}
//打印
void SqStackPrint(PSqStack s)
{
assert(s);
if (0 == s->_size)
return;
for (int i = 0; i < s->_size; i++)
{
printf("(%d,%d)->", s->_array[i]);
}
printf("出来了\n");
}
递归求解
思路:
- 通第一种方法相似,只是每次走一步向四个方向探测,如果可以走通,则缩小当前迷宫,知道最终找到出口
- 代码如下
int _PassMaze(PMaze m,Position entry, Position cur,PSqStack s)
{
Position next;
assert(m);
assert(s);
//先检测是否能走通,如果能走通,则入栈
if (IsPass(m, cur))
{
SqStackPush(s, cur);
//检测是否为出口,如果是则标记
if (IsExit(m, cur, entry))
{
m->_map[cur._x][cur._y] = 2;
return 1;
}
m->_map[cur._x][cur._y] = 2;
//up
next = cur;
next._x += 1;
if (_PassMaze(m, entry, next, s))
return 1;
//left
next = cur;
next._y-= 1;
if (_PassMaze(m, entry, next, s))
return 1;
//right
next = cur;
next._y += 1;
if (_PassMaze(m, entry, next, s))
return 1;
//down
next = cur;
next._x -= 1;
if (_PassMaze(m, entry, next, s))
return 1;
//如果四个方向都走不通,说明走错了,出栈
m->_map[cur._x][cur._y] = 3;
SqStackPop(s);
}
return 0;
}
void PassMaze(PMaze m, Position entry, PSqStack s)
{
assert(m);
assert(s);
if (!IsValidEntry(m, entry))
{
printf("迷宫入口不合法!\n");
return;
}
_PassMaze(m, entry, entry, s);
}