迷宫问题是堆栈应用中的一个经典问题。
迷宫算法有很多种写法,这里总结一下。
如果采用堆栈进行迷宫探测,则称之为深度优先搜索(DFS),它和递归的探测思路是基本一致的,可以看成是递归方式的非递归版本;
如果采用队列进行迷宫探测,则是广度优先搜索(BFS),广度优先搜索法利用队列的特点,一层层向外扩展查找可走的方块,直到找到出口为止,最先找到的这个答案就必然是最短的。
如果打比喻来说,DFS更适合模拟机器人走迷宫的方式,看到一个方向是通的,就一直走下去,遇到死胡同就退回;BFS则好比一个人站在迷宫入口处,拿出一堆小探测器,每个小探测器帮他搜索一个可能的路径去寻找,第一个找到出口的探测器发出了反馈,那么这个人就按照这个小探测器找到的路径走迷宫就行了。
LinkStack.h:
class Box {
public:
int x, y;
int di;
}; //路径的每一步 di表示当前格子下一步往哪里走 有0,1,2,3四种方向
template <class DataType>
struct Node {
DataType data;
Node<DataType>* next;
};
template <class DataType>
class LinkStack
{
private:
Node<DataType>* top;
public:
LinkStack();
~LinkStack();
void push(DataType x);
DataType pop();
DataType getTop();
bool isEmpty();
};
typedef LinkStack<Box> BoxStack; //定义一种模板 直接使用即可
LinkStack.cpp:
#include <iostream>
#include "LinkStack.h"
template <class DataType>
LinkStack<DataType>::LinkStack()
{
top = NULL;
}
template <class DataType>
LinkStack<DataType>::~LinkStack()
{
while (top != NULL)
{
Node<DataType>* p = top;
top = top->next;
delete p;
p = NULL;
}
delete top;
top = NULL;
}
template <class DataType>
void LinkStack<DataType>::push(DataType x)
{
//先准备好一个节点 然后指向原来的节点,然后再把top指针上移
Node<DataType>* s = new Node<DataType>;
s->data = x;
s->next = top;
top = s;
}
template <class DataType>
DataType LinkStack<DataType>::pop()
{
/*if (top == NULL)
return -1;
遗留问题:如果到栈底了返回值应该return什么?*/
DataType x = top->data;
Node<DataType>* p = top;
top = top->next;
delete p;
p = NULL;
return x;
}
template <class DataType>
DataType LinkStack<DataType>::getTop()
{
return top->data;
}
template <class DataType>
bool LinkStack<DataType>::isEmpty()
{
if (top == NULL) {
return true;
}
else
{
return false;
}
}
template class LinkStack<Box>;
DFS_maze.cpp:
#include <iostream>
#include "LinkStack.h"
using namespace std;
const int M = 6;
const int N = 6;
class Direction {
public:
int incX, incY;
};
//迷宫关键代码
bool findPath(int maze[][N],Direction direct[], BoxStack &s) {
Box temp;
int x, y, di;
int line, col;
maze[1][1] = -1;
temp.x = 1;
temp.y = 1;
temp.di = -1;
s.push(temp);
while (!s.isEmpty()) {
temp = s.pop();
x = temp.x;
y = temp.y;
di = temp.di+1;
while (di < 4)
{
line = x + direct[di].incX;
col = y + direct[di].incY;
if (maze[line][col] == 0) {
temp.x = x;
temp.y = y;
temp.di = di;
s.push(temp);
x = line;
y = col;
maze[line][col] = -1;
if (x == M-2 && y == N-2) {
return true;
}
else
{
di = 0;
}
}
else
{
di++;
}
}
}
return false;
}
int main()
{
//输入迷宫 迷宫要求:外围必须全是墙(也就是为数值1)
int maze[M][N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
cin >> maze[i][j];
}
}
//路径栈BoxStack
BoxStack s1;
//定义上、下、左、右
Direction direct[4];
direct[0].incX = 0;
direct[0].incY = 1;
direct[1].incX = 1;
direct[1].incY = 0;
direct[2].incX = 0;
direct[2].incY = -1;
direct[3].incX = -1;
direct[3].incY = 0;
findPath(maze,direct, s1);
while (!s1.isEmpty()) {
Box b1 = s1.pop();
cout << b1.x << " "<< b1.y <<" " << b1.di << endl;
} //尚未实现倒序输出路径
findPath(maze,direct, s1);
cout << s1.pop().x;
system("pause");
return 0;
}
学习参考视频:懒猫老师