迷宫问题(栈的应用)

问题描述:

    以M*N的矩阵表示迷宫图,数字0代表通路,数字1代表障碍。对于走过的路径,将数字0替换为数字2,便于查看通路路径。计算机解迷宫通常用的是“穷举求解”方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回(回溯),换一个方向继续探索,直至出口位置,求得一条通路。

注:对于迷宫的矩阵,我们不必每次从cmd端输入,可在文档中以txt的形式定义保存,其相对路径为当前工程目录下,绝对路径为任意位置,但在打开该文件时,要提供该文件的详细路径名。(本程序定义的MazeMap迷宫图保存在桌面上)

#define _CRT_SECRUE_NO_WARNINGS
#include<iostream>
#include<stack>
#include<cassert>
using namespace std;
#define N 10

struct Pos
{
	int _row;//矩阵行
	int _col;//矩阵列
	Pos(int row,int col)
		:_row(row)
		, _col(col)
	{}
};

template<class T>
bool SearchMazePath(int* arr, int n, Pos entry, stack<T>& paths)    //寻找迷宫的通路。
{
	assert(arr);

	paths.push(entry);
	while (!paths.empty())
	{
		Pos cur = paths.top();
		arr[cur._row*n + cur._col] = 2;//走过的路径用2标识
		if (cur._row == n - 1)//到达矩阵的下边界即为找到出口
		{
			return true;
		}

		//向上探索
		Pos tmp = cur;
		--tmp._row;
		if (arr[tmp._row*n + tmp._col] == 0)
		{
			paths.push(tmp);
			continue;
		}

		//向下探索
		tmp = cur;
		++tmp._row;
		if (arr[tmp._row*n + tmp._col] == 0)
		{
			paths.push(tmp);
			continue;
		}

		//向左探索
		tmp = cur;
		--tmp._col;
		if (arr[tmp._row*n + tmp._col] == 0)
		{
			paths.push(tmp);
			continue;
		}

		//向右探索
		tmp = cur;
		++tmp._col;
		if (arr[tmp._row*n + tmp._col] == 0)
		{
			paths.push(tmp);
			continue;
		}

		paths.pop();    //若上下左右都不通,则回溯。
	}

	return false;
}


//读入迷宫
void GetMaze(int* arr,int n)
{
	assert(arr);
	FILE* fout = fopen("C:\\Users\\Administrator.T47BQSRAR0SRP03\\Desktop\\MazeMap.txt","r");//绝对路径,若为相对路径,直接输入文件名即可(在当前工程目录下)
	assert(fout);//若矩阵传入失败,可直接在崩溃时捕捉拦截,快速显示其问题。防御式编程的一种

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			while (true)
			{
				int tmp = fgetc(fout);
				if (tmp == '0' || tmp == '1')//只显示0,1,跳过了空格等其他字符
				{
					arr[i*n + j] = tmp - '0';
					break;
				}
			}
		}
	}
}


//输出迷宫
void PrintMaze(int* arr, int n)
{
	for (int i = 0; i < n;i++)
	{
		for (int j = 0; j < n;j++)
		{
			cout << arr[i*n + j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}


//测试用例
void Test()
{
	int arr[N][N] = {};//N由宏预编译阶段替换
	Pos sp(2, 0);//入口坐标

	GetMaze((int*)arr, N);
	PrintMaze((int*)arr, N);
	stack<Pos> paths;//创建路径栈

	SearchMazePath((int*)arr, N, sp, paths);//二维数组实际存储是一维数组,所以强制转换成一维用于传参。
	PrintMaze((int*)arr, N);
}

int main()
{
	Test();
	return 0;
}

注:对于当前位置为“死路”时,需要进行回溯,退回到最近一次可走的位置点,但是每一次的回退依然存在上下左右的判断,性能上依旧可以优化,可以借助递归的方式简化回退的重复探索问题,并且对于存在多条通路路径时,还存在最优的路径问题,即最短路径的判断,所以说该程序只是迷宫问题的基础实现。。

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/Xiao__Tian__/article/details/51142117
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞