下面简单阐述下使用栈(循环)和使用递归来走迷宫的区别:
使用递归:
分为两个部分:
一部分为已走过的路径(通路)
另一问题是:递归的子问题(根据下一个可以通的位置继续查找出口)。
将走过的路径保存在栈帧内。
递归结束时返回上一层栈帧,销毁当前栈帧。使用栈(保存走过的路径)
分为两个部分:
一部分为已走过的路径(通路),将其保存在栈内
另一部分为:
试探四个方向,沿着某个可以走通的方向一直试探下去,直到走不通时,退出栈顶元素,栈顶元素始终为当前所处的位置。
1.递归走迷宫:
(利用回溯法)
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<cassert>
struct Pos//设置坐标
{
Pos(int x, int y)
:_x(x)
, _y(y)
{}
int _x;
int _y;
};
template<size_t M,size_t N>
class Maze
{
public:
Maze(int **arr, FILE* fp)//构造迷宫
:_row(M)
, _col(N)
, _maze(arr)
{
int ch = 0;
assert(fp);
for (size_t i = 0; i < _row; ++i)//从文件中读取迷宫
{
for (size_t j = 0; j < _col;)
{
char ch = fgetc(fp);
if (ch == '0' || ch == '1')
{
_maze[i][j] = ch - '0';
++j;
}
}
}
fclose(fp);
}
bool PassMaze(Pos Entry)
{
//递归算法
Pos cur = Entry;
Pos next = cur;
_maze[next._x][next._y] = 2;//将走过的路进行标记
//判断是否为出口
if (next._x == N - 1)
{
return true;
}
//向上查探
next._x -= 1;
if (_CheckAccess(next))
{
if (PassMaze(next))
{
return true;
}
}
//向右查探
next = cur;
next._y += 1;
if (_CheckAccess(next))
{
if (PassMaze(next))
{
return true;
}
}
//向下查探
next = cur;
next._x += 1;
if (_CheckAccess(next))
{
if (PassMaze(next))
{
return true;
}
}
//向左查探
next = cur;
next._y -= 1;
if (_CheckAccess(next))
{
if (PassMaze(next))
{
return true;
}
}
//走到死胡同时标记为3
_maze[cur._x][cur._y] = 3;
return false;
}
~Maze()
{
for (int i = 0; i <_row; ++i)
{
delete[] _maze[i];
}
delete[] _maze;
}
friend ostream& operator<<(ostream& out, Maze& m);
protected:
bool _CheckAccess(Pos cur)
{
if (cur._x >= 0 && cur._x < N && cur._y >= 0 && cur._y < N && _maze[cur._x][cur._y] == 1)
{
return true;
}
return false;
}
private:
int** _maze;
int _row;
int _col;
};
ostream& oper