栈的应用_DFS解迷宫问题

深度优先搜索DFS求解迷宫问题

找到迷宫的可行路径的坐标,这是一个搜索遍历问题。

实现思路:

可行的路径保存在路径向量P中,从当前点寻找可行方向,如果可行则next入栈,不行则出栈退回前一点。

搜寻可行路径的代码:

 while (!P.empty())
	 {
		 if (P.back().direction < d)//d是方向个数,表示可行
		 {
			 point next= {	P.back().pt.x+delta[P.back().direction].x,
							P.back().pt.y + delta[P.back().direction].y };//下一个点
			 ++P.back().direction;
			 if (maze[next.x][next.y] == unvisited)//未被访问
			 {
				 maze[next.x][next.y] = visited;
				 P.push_back({ next,0 });//放进路径里
				 if (next.x == destination.x&&next.y == destination.y)//到达终点
					 break;
			 }
		 }
		 else
			 P.pop_back();//,点无路可走时,出栈返回上一个点
	 }

坐标轴:假定朝下为x轴正方向,朝右为y轴正方向
在这里插入图片描述

这里可以移动方向分为上下左右四种(d=4)情况,它们相对于当前点的方向偏移量如下:
右:{0,1}
下:{1,0}
左:{0,-1}
上:{-1,0}
构成方向向量:以下标取值0, 1, 2, 3标记右,下,左,上与当前点的偏移量.
point delta[d]={{0,1},{1,0},{0-1},{-1,0}};
举例子:delta[0]表示向右走,delta[1]表示向下走。
下个点next表示为:当前点的位置坐标+偏移量

 point next= {	P.back().pt.x + delta[P.back().direction].x,
				P.back().pt.y + delta[P.back().direction].y };//下一个点

完整代码:

#include"pch.h"
#include <iostream>
#include <vector>


using namespace std;

//点坐标
struct point {
	int x;
	int y;
};
//状态:点坐标+方向
struct status {
	point pt;
	int direction;  // 以direction取值0, 1, 2, 3标记东南西北.
};

int main()
{
	const int m = 5;
	const int n = 7;
	char maze[m][n] = { 
		{'*','*','*','*','*', '*','*'},
		{'*','0','*', '0','0','0','*'},
		{'*','0','*', '0','*','0','*'},
		{'*','0','0', '0','*','0','*'},
		{'*','*','*', '*','*','*','*'}
	};
	
	const char visited = 'V';//访问过的标记
	const char unvisited = '0';//未访问过的标记
	//可行的方向数目0,1,2,3分别代表东南西北方向和当前位置的偏移量
	 const int  d = 4;
	 const point delta[d] = { {0,1},{1,0},{0,-1},{-1,0}};
	 //起点和终点坐标
	 point source = { 1,1 };
	 point destination = {3,5};

	 vector<status> P;//搜索时保存路径所用的向量,可视为栈;
	 P.reserve(m*n);//提前预留容量;
	 P.push_back({ source,0 });//设定初始位置,并设定初始方向;
	 maze[source.x][source.y] = visited;//起点定为已经访问

	 while (!P.empty())
	 {
		 if (P.back().direction < d)//方向可取d是方向个数
		 {
			 point next= {	P.back().pt.x+delta[P.back().direction].x,
							P.back().pt.y + delta[P.back().direction].y };//下一个点
			 ++P.back().direction;
			 if (maze[next.x][next.y] == unvisited)//未被访问
			 {
				 maze[next.x][next.y] = visited;
				 P.push_back({ next,0 });//放进路径里
				 if (next.x == destination.x&&next.y == destination.y)//到达终点
					 break;
			 }
		 }
		 else
			 P.pop_back();//,点无路可走时,出栈返回上一个点
	 }

	cout << "迷宫图如下:" << endl;
//print the maze
	for (size_t i = 0; i < m; ++i)
		for (size_t j = 0; j < n; ++j)
		{
			cout << maze[i][j];
			if (j == n - 1)
				cout << endl;
		}
//打印路径
	cout << "可行坐标路径为:" << endl;
	for (const auto& c : P)
		cout << c.pt.x << " " << c.pt.y << endl;
		

	return 0;
}

测试结果:
在这里插入图片描述

发布了115 篇原创文章 · 获赞 70 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/shizheng_Li/article/details/104485085