赞
踩
DFS(Depth-First-Search)不同于BFS广度优先搜索,它更加侧重于对树/图进行深度搜索,在搜索时,从根节点开始一直往下到没有节点可以搜索为止,在搜索过程中可将路径进行保存。实现DFS深度优先搜索可借用“栈”来实现,递归或者非递归的方法均可,在解决迷宫问题时,在寻找迷宫出口问题上使用DFS是个合适的选择。
如图上所示,灰色部分为墙壁,如果想从“起点”位置到达“终点”,使用DFS时,会将所有“可能”的路径都走一遍,直到无路可走仍未发现终点时,将退回至最近一次分叉路口从另一条路继续往下寻找,直到找到终点位置。
第一次向左走至尽头,没有发现终点,则回到“起点”处,开始往下寻找。
当走到“黑色箭头”标记处时,发现该节点为“分叉点”,故DFS记录这个位置,选择一条路径开始往下寻找。
往下走到尽头后发现找不到尽头,故退回到“分叉点”,开始往右边寻找。
向右走又出现了分叉点,故DFS记录这个位置,选择一条路径开始往上寻找。
走到尽头后发现没有到终点所以回到最近一次“分叉点”进行往下寻找。
找到终点,结束。
DFS最经典的问题之一,寻找迷宫中起点到终点的路径:{{0, 0, 1, 0, 1},
{0, 1, 1, 1, 0},
{0, 0, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 1, 0}};
2.1.记录二维网格坐标位置、是否为墙壁、是否走过等状态
- struct Node
- {
- int _x;
- int _y;
- int _value;
- bool _IsWall;
- bool _IsWalked;
- };
-
- vector<std::vector<Node>> Push_Node(std::vector<std::vector<int>>& push_into)
- {
- std::vector<std::vector<Node>> push;
- int state;
-
- for (int i = 0; i < push_into.size(); i++)
- {
- std::vector<Node> into;
- for (int j = 0; j < push_into[i].size(); j++)
- {
- if (push_into[i][j] == 1)
- state = true;
- else
- state = false;
-
- Node node{ i,j,push_into[i][j],state,false };
- into.push_back(node);
- }
- push.push_back(into);
- }
-
- return push;
- }
2.2.寻找指定节点的相邻节点,详细代码可参考我之前写过的文章:【C/C++】获取二维数组相邻八个/四个方向的数据
- std::vector<Node> Find_Beighbors(int x, int y, std::vector<std::vector<Node>>& vec)
- {
- int max_x = (vec.size() - 1);
- int max_y = ((vec[x].size()) - 1);
- std::vector<Node> list; //扩列存储相邻元素
-
- for (int dx = (x > 0 ? -1 : 0); dx <= (x < max_x ? 1 : 0); ++dx)
- {
- for (int dy = (y > 0 ? -1 : 0); dy <= (y < max_y ? 1 : 0); ++dy)
- {
- if ((dx == 0 || dy == 0) && (dx + dy != 0))
- {
- list.push_back(vec[x + dx][y + dy]);
- }
- }
- }
- return list;
- }
2.3.核心部分,使用递归进行DFS搜索,递归使用的是系统的栈,简称隐式栈
- bool DFS(Node root, Node target, vector<vector<Node>>& push_into) //递归调用,隐形栈
- {
- if (root._x == target._x && root._y == target._y)
- return true;
-
- push_into[root._x][root._y]._IsWalked = true;
- vector<Node> Beighbors = Find_Beighbors(root._x, root._y, push_into);
-
- for (int i = 0; i < Beighbors.size(); i++)
- {
- if (!push_into[Beighbors[i]._x][Beighbors[i]._y]._IsWall)
- {
- if (!push_into[Beighbors[i]._x][Beighbors[i]._y]._IsWalked)
- {
- push_into[Beighbors[i]._x][Beighbors[i]._y]._IsWalked = true;
- if (DFS(push_into[Beighbors[i]._x][Beighbors[i]._y], target, push_into))
- {
- push_into[Beighbors[i]._x][Beighbors[i]._y]._value = 3; //标记路径
- printf("(%d,%d)\n",push_into[Beighbors[i]._x][Beighbors[i]._y]._x, push_into[Beighbors[i]._x][Beighbors[i]._y]._y);
- return true;
- }
- }
- }
- }
- return false;
- }
起始节点坐标:(0,0),目标节点坐标:(4,4),输出为:
起始节点坐标:(0,0),目标节点坐标:(4,2),输出为:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。