栈求解迷宫问题

问题:假设下图1是某迷宫的地图(0代表路径,1代表墙壁),问此迷宫是否有条通路?

《栈求解迷宫问题》

求解思想:

用栈来实现解决问题,主要步骤是

(1)将迷宫的入口坐标设为当前坐标

(2)将当前坐标压栈,将当前坐标上的值设为2(0变为2),代表已走过的路

(3)判断当前坐标的四周(上下左右)是否是可以通(为0则通)的,如果是通的,那就将它的坐标设为当前坐标

(4)重复(2)(3)的操作

(5)若遇到如图1中标注的坐标,四周都不可以通(四周都不为0),那么就回退(将栈中的坐标弹出),将栈顶坐标设为当前坐标,重复步骤(3)

(6)当退回到两路的相交处则当前周围有路可以通,重复步骤(2)(3)

(7)只要判断当前位置在迷宫地图的边缘(只有边界值为0时,当前位置才可以到达边界),那么就可以判断该迷宫是否可以通

栈中的元素是迷宫通路的路线,若栈为空,则迷宫没有通路

解题程序:

//Maze.h
#include<iostream>
#include<stack>
#include<assert.h>
using namespace std;

struct Pos
{
	int _row; //行
	int _col;//列
};
//Maze.cpp
#include "Maze.h"

bool CheckPath(int *a, Pos next, int n)
{
	if (next._col < n && next._col >= 0
		&& next._row >= 0 && next._row < n
		&& (a[next._row*n + next._col] == 0))//若行列都合法且该位置元素为0则为真
		return true;
	return false;
}
void GetMaze(int *a, int n)
{
	FILE* fout = fopen("MazeMap.txt", "r");//迷宫地图在放在当前目录下“MazeMap.txt”里
	assert(fout);

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n;)
		{
			char ch = fgetc(fout);//读文件
			if ((ch == '0') || (ch == '1'))//若为0或1则放入数组
			{
				a[i*n + j] = ch - '0';
				j++;
			}
			else
			{
				continue;
			}
		}
	}
	fclose(fout);//关闭文件
}
void PrintMaze(int *a, int n)//打印迷宫
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cout << a[i*n + j] << " ";
		}
		cout << endl;
	}
	cout << endl;

}
bool MazePath(int *a, int n, Pos entry, stack<Pos>& path)//判断迷宫是否有通路
{
	Pos cur = entry;//将出口当做当前位置
	Pos next;
	path.push(cur);
	while (!path.empty())//若栈不为空
	{
		if (cur._col!=entry._col && cur._row!=entry._row
			&&( cur._col==n-1 || cur._col==0 || cur._row ==n-1 || cur._row ==0))//若该位置的行是最后一行,代表已走到出口位置
		{
			return true;
		}
		a[cur._row*n + cur._col] = 2;//将该位置置为2,代表已走过的路

		next = cur;
		next._col++;//若下一个位置是当前位置的右边
		if (CheckPath(a, next, n))//若下一个位置的值合法且为0(可以通),则跳到下一个位置,且压栈
			//若不可以通那么就判断令一个方向的位置的值
		{
			cur = next;
			path.push(cur);
			continue;
		}

		next = cur;
		next._row++;
		if (CheckPath(a, next, n))//同理
		{
			cur = next;
			path.push(cur);
			continue;
		}
		next = cur;
		next._row--;
		if (CheckPath(a, next, n))//同理
		{
			cur = next;
			path.push(cur);

			continue;

		}
		next = cur;
		next._col--;
		if (CheckPath(a, next, n))//同理
		{
			cur = next;
			path.push(cur);

			continue;
		}
		cur = path.top();//当四周都不可以通则回退,将当前位置置为栈顶元素的坐标位置
                path.pop();//顶元素弹出
	}
	return false;//若栈为空,那么迷宫没有通路
}
//test.cpp
#include "Maze.h"
int const n = 10;

void TestMaze()
{
	int a[n][n] = {};
	GetMaze((int *)a, n);
	PrintMaze((int *)a, n);
	stack<Pos> path;
	Pos entry = { 2, 0 };
    bool ret = MazePath((int *)a, n, entry, path);
	cout << "是否有通路" << ret << endl;
	PrintMaze((int *)a, n);

}
int main()
{
	TestMaze();
	getchar();
	return 0;
}

运行结果:

当迷宫有出口,则运行结果如图:返回1

《栈求解迷宫问题》

当迷宫没有出口时,运行结果如下图:返回1

《栈求解迷宫问题》

 

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