栈和队列实现迷宫路径搜索

题目

自定义一个迷宫,行、列值>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;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早安不安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值