题目
自定义一个迷宫,行、列值>8,它有一个出口和一个入口,先输出迷宫图形,然后找出一条从入口到出口的路径
基本接口:
class MazeWay {
public:
// 定义迷宫
vector<vector<int>> mazeSet = { {1,1,1,1,1,1,1,1,1,1,1},{1,1,0,0,0,0,0,0,0,0,1},
{1,1,0,0,1,1,1,1,1,0,1},{1,1,1,0,0,0,1,0,1,0,1},
{1,1,1,1,0,1,0,1,1,1,1},{1,0,1,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,1,1,0,1},{1,0,0,0,1,0,0,0,1,0,1},
{1,1,1,1,1,0,1,0,1,0,1},{1,0,0,0,1,0,1,0,1,0,1},
{1,0,1,0,0,0,1,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1}};
//vector<vector<int>> mazeSet = { {1,1,1,1,1,1,1,1,1,1,1,1,1},{1,0,0,0,0,0,0,0,0,0,0,0,1},
// {1,0,0,0,0,0,1,1,1,1,1,0,1},{1,1,1,1,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,1,0,1,0,0,0,0,0,1},{1,0,0,0,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,1,0,1,0,0,0,0,0,1},{1,0,1,1,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,0,0,1,0,0,0,0,0,1},{1,0,0,0,1,0,1,1,1,1,1,0,1},
// {1,0,0,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1,1} };
//pair<int, int> beginN{ 5,3 },endN{3,7};
pair<int, int> beginN{ 3,9 }, endN{ 10,1 }; // 定义终点和起始点
void showMaze(vector<vector<int>> mazeGet); // 迷宫可视化
int findWay(vector<vector<int>> mazeMap, pair<int, int> &place); // 查找路线
stack<pair<int,int>> mazePathStack(vector<vector<int>> mazeGet); // 主函数(栈实现)
vector<pair<int,int>> mazePathQueue(vector<vector<int>> mazeGet); // 主函数(队列实现)
};
栈实现
思想
通过回溯法进行路径搜索,先朝一个指定的方向进行不断的前行,如果没有找到路,不断沿走过的路回退,找到没有走过的路,寻找新的路去走。
额,可能表述的不是很清楚,具体可以Baidu一下回溯法,有很多大神讲的不错。
代码实现
int MazeWay::findWay(vector<vector<int>> mazeMap, pair<int, int>& place)
{
// 上
if (mazeMap[place.first - 1][place.second] == 0) {
place.first--;
return 1;
}
// 右
else if (mazeMap[place.first][place.second + 1] == 0) {
place.second++;
return 1;
}
// 下
else if (mazeMap[place.first + 1][place.second] == 0) {
place.first++;
return 1;
}
// 左
else if (mazeMap[place.first][place.second - 1] == 0) {
place.second--;
return 1;
}
return 0;
}
// 栈实现迷宫路径查找
stack<pair<int, int>> MazeWay::mazePathStack(vector<vector<int>> mazeGet)
{
stack<pair<int, int>> waySign;
waySign.push(beginN);
pair<int, int> NodeSin;
while (!waySign.empty()) {
NodeSin = waySign.top();
if (NodeSin == endN)return waySign; // 找到终点,出口
mazeGet[NodeSin.first][NodeSin.second]--; // 走过的路做标记
findWay(mazeGet, NodeSin); // 找没有走过的路
if (NodeSin != waySign.top()) { // 如果找到了路
waySign.push(NodeSin); // 插入新路
}
else waySign.pop(); // 没有找到路,退回重新找路
}
return stack<pair<int, int>>(); // 没有找到路,返回空
}
队列实现
思想
通过广度优先的方式进行路径搜索,将所有可以走的路进行搜索,将现在所有可能走的路存储到队列,然后再不断提取和存储新的可能路线。
如果还是觉得不太理解的话,也还是百度吧(泪奔)
代码实现
vector<pair<int, int>> MazeWay::mazePathQueue(vector<vector<int>> mazeGet)
{
queue<vector<pair<int, int>>> waySearch;
vector<pair<int,int>> waySave = { beginN };
waySearch.push(waySave);
while (!waySearch.empty())
{
waySave = waySearch.front();
waySearch.pop();
for (int i = -1; i < 2; i ++) {
for (int j = -1; j < 2; j++)
{
if (i && j)continue;
auto waySet = waySave;
pair<int, int> node = { waySet.back().first + i ,waySet.back().second + j };
if (node.first == endN.first && node.second == endN.second) {
waySet.push_back(node);
return waySet;
}
if (!mazeGet[node.first][node.second]) {
mazeGet[node.first][node.second] = 1;
waySet.push_back(node);
waySearch.push(waySet);
}
}
}
}
return vector<pair<int, int>>();
}
完整代码
#include<stdio.h>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
using namespace std;
/*
// 迷宫布局
12 * 11
■■■■■■■■■■■
■■ ■
■■ ■■■■■ ■
■■■ ■ ■起■
■■■■ ■ ■■■■
■ ■ ■
■ ■ ■■■■■ ■
■ ■ ■ ■
■■■■■ ■ ■ ■
■ ■ ■ ■ ■
■终■ ■ ■
■■■■■■■■■■■
*/
/*
// 迷宫布局
12 * 11
■■■■■■■■■■■■■
■ ■
■ ■■■■■ ■
■■■■■ ■起 ■
■ ■ ■ ■
■ 终■ ■ ■
■ ■■■ ■ ■
■ ■ ■
■ ■■■■■ ■
■ ■
■ ■
■■■■■■■■■■■■■
*/
class MazeWay {
public:
// 定义迷宫
vector<vector<int>> mazeSet = { {1,1,1,1,1,1,1,1,1,1,1},{1,1,0,0,0,0,0,0,0,0,1},
{1,1,0,0,1,1,1,1,1,0,1},{1,1,1,0,0,0,1,0,1,0,1},
{1,1,1,1,0,1,0,1,1,1,1},{1,0,1,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,1,1,1,0,1},{1,0,0,0,1,0,0,0,1,0,1},
{1,1,1,1,1,0,1,0,1,0,1},{1,0,0,0,1,0,1,0,1,0,1},
{1,0,1,0,0,0,1,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1}};
//vector<vector<int>> mazeSet = { {1,1,1,1,1,1,1,1,1,1,1,1,1},{1,0,0,0,0,0,0,0,0,0,0,0,1},
// {1,0,0,0,0,0,1,1,1,1,1,0,1},{1,1,1,1,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,1,0,1,0,0,0,0,0,1},{1,0,0,0,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,1,0,1,0,0,0,0,0,1},{1,0,1,1,1,0,1,0,0,0,0,0,1},
// {1,0,0,0,0,0,1,0,0,0,0,0,1},{1,0,0,0,1,0,1,1,1,1,1,0,1},
// {1,0,0,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1,1} };
//pair<int, int> beginN{ 5,3 },endN{3,7};
pair<int, int> beginN{ 3,9 }, endN{ 10,1 }; // 定义终点和起始点
void showMaze(vector<vector<int>> mazeGet); // 迷宫可视化
int findWay(vector<vector<int>> mazeMap, pair<int, int> &place); // 查找路线
stack<pair<int,int>> mazePathStack(vector<vector<int>> mazeGet); // 主函数(栈实现)
vector<pair<int,int>> mazePathQueue(vector<vector<int>> mazeGet); // 主函数(队列实现)
};
int MazeWay::findWay(vector<vector<int>> mazeMap, pair<int, int>& place)
{
// 上
if (mazeMap[place.first - 1][place.second] == 0) {
place.first--;
return 1;
}
// 右
else if (mazeMap[place.first][place.second + 1] == 0) {
place.second++;
return 1;
}
// 下
else if (mazeMap[place.first + 1][place.second] == 0) {
place.first++;
return 1;
}
// 左
else if (mazeMap[place.first][place.second - 1] == 0) {
place.second--;
return 1;
}
return 0;
}
// 栈实现迷宫路径查找
stack<pair<int, int>> MazeWay::mazePathStack(vector<vector<int>> mazeGet)
{
stack<pair<int, int>> waySign;
waySign.push(beginN);
pair<int, int> NodeSin;
while (!waySign.empty()) {
NodeSin = waySign.top();
if (NodeSin == endN)return waySign; // 找到终点,出口
mazeGet[NodeSin.first][NodeSin.second]--; // 走过的路做标记
findWay(mazeGet, NodeSin); // 找没有走过的路
if (NodeSin != waySign.top()) { // 如果找到了路
waySign.push(NodeSin); // 插入新路
}
else waySign.pop(); // 没有找到路,退回重新找路
}
return stack<pair<int, int>>();// 没有找到路,返回空
}
vector<pair<int, int>> MazeWay::mazePathQueue(vector<vector<int>> mazeGet)
{
queue<vector<pair<int, int>>> waySearch;
vector<pair<int,int>> waySave = { beginN };
waySearch.push(waySave);
while (!waySearch.empty())
{
waySave = waySearch.front();
waySearch.pop();
for (int i = -1; i < 2; i ++) {
for (int j = -1; j < 2; j++)
{
if (i && j)continue;
auto waySet = waySave;
pair<int, int> node = { waySet.back().first + i ,waySet.back().second + j };
if (node.first == endN.first && node.second == endN.second) {
waySet.push_back(node);
return waySet;
}
if (!mazeGet[node.first][node.second]) {
mazeGet[node.first][node.second] = 1;
waySet.push_back(node);
waySearch.push(waySet);
}
}
}
}
return vector<pair<int, int>>();
}
void MazeWay::showMaze(vector<vector<int>> mazeGet) // 迷宫可视化
{
for (int i = 0; i < mazeGet.size(); i++) {
for (int j = 0; j < mazeGet[0].size(); j++) {
if (i == beginN.first && j == beginN.second)
{
cout << "起";
continue;
}
else if (i == endN.first && j == endN.second)
{
cout << "终";
continue;
}
else if (mazeGet[i][j]==1)cout << "■";
else if (mazeGet[i][j] == 0)cout << " ";
else cout << "╬ ";
}
cout << "\n";
}
}
int main() {
MazeWay run_queue;
auto wayGetQueue = run_queue.mazePathQueue(run_queue.mazeSet);
cout << "原始迷宫:" << endl;
run_queue.showMaze(run_queue.mazeSet);
if (wayGetQueue.empty())cout << "没有找到路" << endl;
else {
for(auto node: wayGetQueue){
run_queue.mazeSet[node.first][node.second] = -1;
}
cout << "\n\n\n队列结果:" << endl;
run_queue.showMaze(run_queue.mazeSet);
}
MazeWay run_way;
auto wayGetStack = run_way.mazePathStack(run_way.mazeSet);
if (wayGetStack.empty())cout << "没有找到路" << endl;
else {
while (!wayGetStack.empty())
{
auto node = wayGetStack.top();
wayGetStack.pop();
run_way.mazeSet[node.first][node.second] = -1;
}
cout << "\n\n\n栈结果:" << endl;
run_way.showMaze(run_way.mazeSet);
}
return 0;
}