一、栈的算法查找迷宫解法
1.代码
按照《数据结构、算法与应用C++语言描述》第九章栈的思路来实现解法。
迷宫内部主要有四个函数。welcome函数是欢迎界面,inputMaze函数是输入迷宫,findPath函数是寻找迷宫解法,outputPath函数是输出迷宫解法。
#include <iostream>
#include "Maze.h"
using namespace std;
int main()
{
Maze m;
m.welcome();
m.inputMaze();
m.findPath();
m.outputPath();
return 0;
}
记录当前位置的类position.h
#ifndef POSITION_H
#define POSITION_H
#include <iostream>
using namespace std;
class position
{
public:
position()
{
this->row = 0;
this->col = 0;
}
position(int r, int c)
{
this->row = r;
this->col = c;
}
~position() {}
int row;
int col;
};
#endif // !POSITION_H
迷宫类Maze.h
#ifndef MAZE_H
#define MAZE_H
#include <iostream>
#include <stack>
#include "position.h"
using namespace std;
class Maze
{
public:
Maze();
~Maze();
void welcome();
void inputMaze();
void findPath();
void outputPath();
private:
int m; //迷宫行数
int n; //迷宫列数
int** maze; //二维指针存取迷宫,(m+2)*(n+2)
stack<position>* path; //迷宫路线
};
#endif // !MAZE_H
迷宫类的实现
#include "Maze.h"
Maze::Maze()
{
m = 0;
n = 0;
}
Maze::~Maze()
{
if (maze != NULL)
{
for (int i = 0; i < m + 2; ++i)
{
delete[] maze[i];
}
delete[] maze;
maze = NULL;
}
if (path != NULL)
{
delete path;
path = NULL;
}
}
void Maze::welcome()
{
cout << "Welcome To A MAZE" << endl;
}
void Maze::inputMaze()
{//返回存取迷宫的二维指针
cout << "请输入迷宫的长和宽:" << endl;
cin >> m >> n;
this->maze = new int* [m + 2];
for (int i = 0; i < m + 2; ++i)
{
maze[i] = new int[n + 2];
maze[i][0] = maze[i][n + 1] = 1; //第一列和最后一列为墙
}
for (int i = 0; i < n + 2; ++i)
{
maze[0][i] = maze[m + 1][i] = 1; //第一行和最后一行为墙
}
cout << "请输入迷宫内容:\n";
//输入迷宫内容,0代表可通,1代表不通
for (int i = 1; i < m + 1; ++i)
{
for (int j = 1; j < this->n + 1; ++j)
{
cin >> maze[i][j];
}
}
}
void Maze::findPath()
{
//定义当前位置移动的4个方向,第0列为行偏移量,第1列为列偏移量
int move[4][2] = { {0,1},{1,0},{0,-1},{-1,0} }; //右,下,左,上
path = new stack<position>; // 存储路径信息
position here(1, 1); //起始位置
maze[1][1] = 1; //防止回到入口
int option = 0; //可选的方向,右、下、左、上=(0,1,2,3)
int max_option = 3; //方向的选择范围
while (here.row != m || here.col != n) //没走到迷宫出口
{
//找到要移动的相邻一步
int r = 0, c = 0;
while (option <= max_option)
{
r = here.row + move[option][0];
c = here.col + move[option][1];
if (maze[r][c] == 0) //可以走通
{
break;
}
++option; //寻找下一个方向
}
if (option <= max_option) //可以接着走通的情况
{
path->push(here); //更新路径
//here更新位置
here.row = r;
here.col = c;
maze[here.row][here.col] = 1; //防止往下寻找时重复访问到此位置
option = 0;
}
else //当走不通时,可以把当前位置置1封死路,返回上一位置
{
if (path->empty())
{
cout << "There Is No Path For This Maze!" << endl;
return;
}
else
{
//返回重新搜索
position next = path->top();
path->pop();
//将当前位置封死,避免重复搜索
maze[here.row][here.col] = 1;
here = next;
option = 0;
}
}
}
path->push(here); //出口位置入栈
cout << "I Find The Path For This Maze!" << endl;
return;
}
void Maze::outputPath()
{
if (path == NULL)
{
cout << "There Is No Path For This Maze!" << endl;
return;
}
char** mazePath = new char* [m];
//拷贝迷宫到mazePath
for (int i = 0; i < m; ++i)
{
mazePath[i] = new char[n];
for (int j = 0; j < n; ++j)
{//四周的墙去掉
if (maze[i + 1][j + 1] == 0)
{
mazePath[i][j] = '0';
}
else if (maze[i + 1][j + 1] == 1)
{
mazePath[i][j] = '1';
}
}
}
//拷贝走出迷宫的路线到mazePath
position tmp;
while (!path->empty())
{
tmp = path->top();
path->pop();
mazePath[tmp.row - 1][tmp.col - 1] = '*'; //去除墙
}
//打印输出迷宫路线
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
cout << mazePath[i][j] << " ";
}
cout << endl;
delete[] mazePath[i]; //删除指针空间
}
delete[] mazePath; //删除指针空间
}
内部实现算法注释已经写得很清楚了,注意最后输出的迷宫算法将查找路线过程也一并显示了,查找过程走错的路线都置为1了。
2.测试用例
测试1:
请输入迷宫的长和宽:
5 5
请输入迷宫内容:
0 1 1 0 0
0 0 1 1 0
1 0 0 1 1
1 0 0 1 0
1 1 0 0 0
测试结果:
测试2:
请输入迷宫的长和宽:
9 8
请输入迷宫内容:
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 1
0 1 1 1 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 0 0 1
1 1 0 0 0 1 0 1
1 1 0 0 0 0 0 0
测试结果: