此题可以使用栈来避开递归,首先需要开辟一个和迷宫具有同样几何形状的结构体二维数组来保存是从哪一个点(坐标)到达该点的(该初始化时将所有的坐标都置为0),还需要一个可以保存坐标的栈。每次将能够走通的点(值为1)都入栈然后在循环的开始处将栈顶元素弹出保存进temp变量(保存坐标的变量)中,访问temp变量四周的元素是否可以被访问,如果可以被访问(值为0)则将对应路径数组中的元素(即对应坐标)值改为temp变量的值并将该能被访问的变量入栈,再将迷宫中的0(能访问)更改为2(已被访问过)防止重复访问。最后从路径数组中的出口处开始倒序输出所走路径即可。
在此种思想中栈保存了所有可以走通的点,当一个点的四周都不能够走通时弹出的该点坐标程序并没有进行任何实质性的处理,所以这就相当于一个“回溯”的过程。而访问四周的点的过程就是一个枚举的过程。
stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include <assert.h>
typedef struct Pos
{
int _col;
int _row;
}Pos;
typedef int Datatype;
typedef struct Stack
{
Pos *_mz;
size_t _size;
size_t _capacity;
}Stack;
void StackInit(Stack** ps, size_t capacity)
{
assert(*ps);
(*ps)->_size = 0;
(*ps)->_capacity = capacity;
(*ps)->_mz = (Pos *)malloc(sizeof(Pos)*(*ps)->_capacity);
return;
}
Pos StackTop(Stack *s)
{
return s->_mz[s->_size - 1];
}
void StackPush(Stack **pps, Pos *x)
{
assert(pps);
assert(*pps);
if ((*pps)->_size == (*pps)->_capacity)
{
(*pps)->_capacity *= 2;
(*pps)->_mz = (Pos*)realloc((*pps)->_mz, (sizeof(Pos))*(*pps)->_capacity);
}
assert(*pps);
((*pps)->_mz[(*pps)->_size])._col = x->_col;
((*pps)->_mz[(*pps)->_size])._row = x->_row;
(*pps)->_size++;
}
Pos *StackPop(Stack *ps)
{
return ps->_mz + (--ps->_size);
}
int StackEmpty(Stack *ps)
{
assert(ps);
return ps->_size;
}
void StackPrint(Stack *ps)
{
int i = 0;
for (i = ps->_size - 1; i >= 0; i--)
printf("(%d,%d)->", ps->_mz[i]._col + 1, ps->_mz[i]._row + 1);
printf("\n");
}
test.c
#include"maze.h"
int main()
{
//Datatype arr[N][N] = {
// { 0,0,0,0,0,0,0 },
// { 0,0,0,1,1,1,1 },
// { 0,0,0,1,0,1,0 },
// { 0,0,0,1,0,1,0 },
// { 0,0,0,1,1,1,1 },
// { 0,0,0,1,0,0,0 },
// { 0,0,0,1,0,0,0 },
//};
Datatype arr[N][N] = {
{ 0,0,0,0,0,0 },
{ 0,0,1,1,1,1 },
{ 0,0,1,0,1,0 },
{ 0,0,1,0,1,0 },
{ 0,0,1,1,1,1 },
{ 0,0,1,0,0,0 },
};
Maze *maze = (Maze*)malloc(sizeof(Maze));
memset(maze, 0, sizeof(Maze));
MazeInit(&maze, arr);
MazePrint(maze);
MazeGetShortPath(maze);
system("pause");
return 0;
}
maze.h
#pragma once
#include"Stack.h"
#define N 6
typedef struct Maze
{
Datatype _mz[N][N];
Pos *_entry;
}Maze;
void MazeInit(Maze **pmaze, Datatype a[N][N])
{
int i = 0, j = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
(*pmaze)->_mz[i][j] = a[i][j];
}
}
(*pmaze)->_entry = (Pos*)malloc(sizeof(Pos));
(*pmaze)->_entry->_col = 5;
(*pmaze)->_entry->_row = 2;
}
void MazePrint(Maze *pmaze) {
int i = 0, j = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
printf("%3d", pmaze->_mz[i][j]);
}
printf("\n");
}
printf("\n");
}
int MazeCheckIsAccess(Maze *pmaze, Pos* pos)
{
if (pos->_col >= 0 && pos->_col < N && pos->_row >= 0 && pos->_row < N)
{
if (pmaze->_mz[pos->_col][pos->_row] == 1)
return 1;
}
return 0;
}
//没有因为找到出口结束,而是等栈为空结束。
int MazeGetPath(Maze *pmaze)
{
Pos *cur = pmaze->_entry;
Pos *next = (Pos*)malloc(sizeof(Pos));
Stack *path = (Stack *)malloc(sizeof(Stack));
StackInit(&path, 10);
StackPush(&path, cur);
int flag = 0;
while (StackEmpty(path) != 0)
{
(*cur) = StackTop(path);
StackPop(path);
pmaze->_mz[cur->_col][cur->_row] = 2;
if (cur->_row == N - 1)
{
flag = 1;
printf("找到了\n");
MazePrint(pmaze);
}
{
/*下*/
next->_col = cur->_col + 1;
next->_row = cur->_row;
if (MazeCheckIsAccess(pmaze, next))
{
StackPush(&path, next);
}
//上
next->_col = cur->_col - 1;
next->_row = cur->_row;
if (MazeCheckIsAccess(pmaze, next))
{
StackPush(&path, next);
}
//左
next->_col = cur->_col;
next->_row = cur->_row - 1;
if (MazeCheckIsAccess(pmaze, next))
{
StackPush(&path, next);
}
//右
next->_col = cur->_col;
next->_row = cur->_row + 1;
if (MazeCheckIsAccess(pmaze, next))
{
StackPush(&path, next);
}
}
}
if (flag == 0)
printf("没有出口\n");
free(next);
return 1;
}
int MazeCheckIsShortAccess(Maze *pmaze, Pos* pos, Pos* next)
{
if (next->_col >= 0 && next->_col < N && next->_row >= 0 && next->_row < N)
{
if ((pmaze->_mz[next->_col][next->_row] == 1) || pmaze->_mz[next->_col][next->_row]>pmaze->_mz[pos->_col][pos->_row])
return 1;
}
return 0;
}
void StackShortPath(Maze *pmaze, Stack *path)
{
int i = 0, j = N - 1;
int shortcount = N * N;
Pos cur;
for (i = 0; i < N; i++)
{
if (pmaze->_mz[i][j] != 0 && pmaze->_mz[i][j] < shortcount)
{
shortcount = pmaze->_mz[i][j];
cur._col = i;
cur._row = j;
}
}
printf("the short path size is:%3d\n", shortcount - 1);
printf("the short path out is:(%d,%d)\n", cur._col + 1, cur._row + 1);
Pos *next = (Pos*)malloc(sizeof(Pos));
StackPush(&path, &cur);
while (cur._col != pmaze->_entry->_col || cur._row != pmaze->_entry->_row)
{
cur = StackTop(path);
{
/*下*/
next->_col = cur._col + 1;
next->_row = cur._row;
if (pmaze->_mz[next->_col][next->_row] == pmaze->_mz[cur._col][cur._row] - 1)
{
StackPush(&path, next);
}
//上
next->_col = cur._col - 1;
next->_row = cur._row;
if (pmaze->_mz[next->_col][next->_row] == pmaze->_mz[cur._col][cur._row] - 1)
{
StackPush(&path, next);
}
//左
next->_col = cur._col;
next->_row = cur._row - 1;
if (pmaze->_mz[next->_col][next->_row] == pmaze->_mz[cur._col][cur._row] - 1)
{
StackPush(&path, next);
}
//右
next->_col = cur._col;
next->_row = cur._row + 1;
if (pmaze->_mz[next->_col][next->_row] == pmaze->_mz[cur._col][cur._row] - 1)
{
StackPush(&path, next);
}
}
}
StackPrint(path);
}
void MazeGetShortPath(Maze *pmaze)
{
Pos cur = *pmaze->_entry;
Pos *next = (Pos*)malloc(sizeof(Pos));
Stack *path = (Stack *)malloc(sizeof(Stack));
StackInit(&path, 10);
Stack *shortpath = (Stack *)malloc(sizeof(Stack));
StackInit(&shortpath, 10);
StackPush(&path, &cur);
pmaze->_mz[cur._col][cur._row] = 2;
int flag = 0;
while (StackEmpty(path) != 0)
{
if (cur._row == N - 1)
{
MazePrint(pmaze);
printf("找到了\n");
flag = 1;
}
cur = StackTop(path);
StackPop(path);
{
/*下*/
next->_col = cur._col + 1;
next->_row = cur._row;
if (MazeCheckIsAccess(pmaze, next))
{
pmaze->_mz[next->_col][next->_row] = pmaze->_mz[cur._col][cur._row] + 1;
StackPush(&path, next);
}
//上
next->_col = cur._col - 1;
next->_row = cur._row;
if (MazeCheckIsAccess(pmaze, next))
{
pmaze->_mz[next->_col][next->_row] = pmaze->_mz[cur._col][cur._row] + 1;
StackPush(&path, next);
}
//左
next->_col = cur._col;
next->_row = cur._row - 1;
if (MazeCheckIsAccess(pmaze, next))
{
pmaze->_mz[next->_col][next->_row] = pmaze->_mz[cur._col][cur._row] + 1;
StackPush(&path, next);
}
//右
next->_col = cur._col;
next->_row = cur._row + 1;
if (MazeCheckIsAccess(pmaze, next))
{
pmaze->_mz[next->_col][next->_row] = pmaze->_mz[cur._col][cur._row] + 1;
StackPush(&path, next);
}
}
}
free(next);
if (flag == 0)
{
printf("没有出口\n");
}
else {
StackShortPath(pmaze, shortpath);
}
return;
}
“`