迷宫问题的递归与非递归写法

#include <iostream>
using namespace std;
#include <stack>

struct Pos//定义坐标点
{
	size_t _row;
	size_t _col;
};

template<size_t M, size_t N>
class Maze
{
protected:
	int _maze[M][N];
	stack<Pos> shortPath;
public:
	Maze(int maze[][N])//构造函数,初始化对象
	{
		for (size_t i = 0; i < M; i++)
		{
			for (size_t j = 0; j < N; j++)
			{
				_maze[i][j] = maze[i][j];
			}
		}
	}

	void print()//打印二维矩阵函数
	{
		for (size_t i = 0; i < M; i++)
		{
			for (size_t j = 0; j < N; j++)
			{
				cout << _maze[i][j] << " ";
			}
			cout << endl;//每行完了换行
		}
		cout << endl;//最后换行
	}

	bool CheckAccess(Pos next,Pos entry)//探测next位置是否可通
	{
		if (next._row < M && next._col < N &&
			((_maze[next._row][next._col] == 0)
				||(_maze[next._row][next._col]>_maze[entry._row][entry._col])))//坐标点合法且这点值为0
		{
			return true;
		}
		return false;
	}

	bool GetPath(Pos entry)//找通路
	{
		//上下左右四个方向探测
		Pos cur, next;//定义当前点、下一个点的坐标
		cur = entry;//让cur来到入口
		stack<Pos> path;
		path.push(entry);


		while (!path.empty())
		{
			cur = path.top();  //
			_maze[cur._row][cur._col] = 2;// 将走过的路设置为2,如果 程序每个来到这,说明是continue上来的,next

										  出口只针对这道题?
			if (cur._row == M - 1)//出口
			{
				return true;
			}

			//上
			next = cur;//让next也先指向入口
			next._row -= 1;
			if (CheckAccess(next))//上可通
			{
				//cur = next;//再以可通的点作为入口
				path.push(next);  //
				continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
			}
			//右
			next = cur;//让next恢复到入口
			next._col += 1;
			if (CheckAccess(next))//上可通
			{
				//cur = next;//再以可通的点作为入口
				path.push(next);
				continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
			}

			//下
			next = cur;//让next恢复到入口
			next._row += 1;
			if (CheckAccess(next))//上可通
			{
				//cur = next;//再以可通的点作为入口
				path.push(next);
				continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
			}

			//左
			next = cur;//让next恢复到入口
			next._col -= 1;
			if (CheckAccess(next))//上可通
			{
				//cur = next;//再以可通的点作为入口
				path.push(next);
				continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
			}

			//回溯
			path.pop();
		}
		return false;
	}











	void GetShortPath(Pos entry, stack<Pos>& path)//递归找通路坐标点
	{
		path.push(entry);

		if (entry._row == M - 1)
		{
			if (shortPath.empty() || path.size() < shortPath.size())
			{
				shortPath = path; // ortPath最短路径
			}
			cout << "找到一个出口" << "[" << entry._row << "," << entry._col << "]" << endl;
			if (!shortPath.empty())
			{
				cout << "最短路径:出口";
				stack<Pos> tmp = shortPath;
				while (!tmp.empty())
				{
					Pos& top = tmp.top();
					printf("[%d,%d]<-", top._row, top._col);
					tmp.pop();
				}
				cout << endl;
			}

			cout << endl;
			return;
		}


		Pos next;
		//上
		next = entry;
		next._row -= 1;
		if (CheckAccess(next,entry))
		{
			_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
			GetShortPath(next, path);
		}

		//右
		next = entry;
		next._col += 1;
		if (CheckAccess(next, entry))
		{
			_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
			GetShortPath(next, path);
		}

		//下
		next = entry;
		next._row += 1;
		if (CheckAccess(next, entry))
		{
			_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
			GetShortPath(next, path);
		}


		//左
		next = entry;
		next._col -= 1;
		if (CheckAccess(next, entry))
		{
			_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
			GetShortPath(next, path);
		}

		path.pop();
	}











	void GetPathR(Pos entry)//递归找通路
	{

		_maze[entry._row][entry._col] = 2;
		if (entry._row == M - 1)
		{
			cout << "找到一个出口" << "[" << entry._row << "," << entry._col << "]" << endl;
			return;
		}

		Pos next;
		//上
		next = entry;
		next._row -= 1;
		if (CheckAccess(next))
		{
			GetPathR(next);
		}

		//右
		next = entry;
		next._col += 1;
		if (CheckAccess(next))
		{
			GetPathR(next);
		}

		//下
		next = entry;
		next._row += 1;
		if (CheckAccess(next))
		{
			GetPathR(next);
		}


		//左
		next = entry;
		next._col -= 1;
		if (CheckAccess(next))
		{
			GetPathR(next);
		}


	}

};




void TestMaze()
{
	int mazeArray[10][10] = { { 1,1,1,1,1,1,1,1,1,1 },
	{ 1,1,1,1,1,1,1,1,1,1 },
	{ 0,0,0,1,1,1,1,1,1,1 },
	{ 1,1,0,1,1,1,1,1,1,1 },
	{ 1,1,0,0,0,0,1,1,1,1 },
	{ 1,1,0,1,1,0,1,1,1,1 },
	{ 1,1,0,1,1,0,1,1,1,1 },
	{ 1,1,0,1,1,0,1,1,1,1 },
	{ 1,1,0,1,1,0,1,1,1,1 },
	{ 1,1,0,1,1,0,1,1,1,1 }
	};
	Maze<10, 10> maze(mazeArray);//用已知数组mazeArray初始化对象maze
	maze.print();
	Pos entry = { 2,0 };
	//if (maze.GetPath(entry))
	//{
	//	cout << "找到通路" << endl;
	//}
	//else
	//{
	//	cout << "找不到通路" << endl;
	//}
	//maze.GetPath(entry);//从入口进去找通路
	//maze.GetPathR(entry);
	stack<Pos> path;
	maze.GetShortPath(entry, path);
	maze.print();
}

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值