深度优先搜索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;
}
测试结果: