DFS 深度优先搜索C++实现(迷宫问题)
DFS(Depth First Search)深度优先搜索C++实现(迷宫问题)
实现代码
#include<bits/stdc++.h>
using namespace std;
const int MAXSIZE = 100;
int maze[MAXSIZE][MAXSIZE];
vector< pair<int, int> > path;//动态数组path用于存储路径
bool flag = true;//用于递归终点返回
int dir[4][2] = {//方向数组{- 1, 0},{1, 0},{0, - 1},{0, 1}
};void DFS(int y, int x){if(!flag) return;if(maze[y][x] == 3){path.push_back(make_pair(y,x));flag = false;return;}if(maze[y][x] == 1) return;//上述判断语句检测是否到达递归终点maze[y][x] = 1;//标记已访问path.push_back(make_pair(y,x));//将此顶点加入路径当中for(int i = 0; i < 4 && flag; i++){//向四个方向继续递归寻找DFS(y + dir[i][0], x + dir[i][1]);}if(flag) path.pop_back();//依据此顶点未找到则退出路径
}int main(int argc, char const *argv[])
{int n, m;int x, y;if(argc == 1){argv[1] = "text.txt";}freopen(argv[1],"r", stdin);while(~scanf("%d%d", &n, &m)){for(int i = 0; i <= n + 1; i++)maze[0][i] = maze[m + 1][i] = 1;for(int i = 0; i <= m + 1; i++)maze[i][0] = maze[i][n + 1] = 1;for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++){scanf("%d", &maze[i][j]);if(maze[i][j] == 2){x = j;y = i;}}//输入数据并设置终点path.push_back(make_pair(y,x));for(int i = 0; i < 4; i++){DFS(y + dir[i][0], x + dir[i][1]);//递归地对四个方向进行查找}//打印结果printf("Steps: %d\n",path.size());printf("Path:\n");for(int i = 0; i < path.size(); i++)printf("%d %d\n", path[i].first, path[i].second);}return 0;
}
算法思路
本算法并未采用邻接矩阵、邻接表等数据结构,只是简单地实现走迷宫的算法,设置方向数组dir进行指向下标y,x的改变,深度优先搜索会从起始点开始沿着被访问顶点的第一个邻接点递归搜索,访问到最“深”的那个点(其邻接点均已被访问)再回溯到上一个点访问第二个顶点,以此类推,直到访问到要找的节点或者访问所有的顶点结束。
测试数据
6 6
2 0 0 0 0 0
1 1 1 1 0 1
1 0 0 0 0 1
1 1 1 1 0 1
1 1 1 1 0 1
3 0 0 0 0 1
测试结果
测试结果打印出的Path是maze数组下标
Steps: 14
Path:
1 1
1 2
1 3
1 4
1 5
2 5
3 5
4 5
5 5
6 5
6 4
6 3
6 2
6 1
最后
本算法用于求解迷宫问题,基于DFS算法,四个方向为自身假设,在图的遍历算法中并不存在类似的方向,只寻找节点的邻接点且含有的最多邻接点数可以是大于0的任意值。若是图过大,可以使用栈来代替递归,或者使用BFS算法,BFS算法和DFS算法均只遍历整张图的每一个顶点一次且仅一次(在进行全图遍历的情况下),故时间复杂度均为O(n),n为图的顶点数,但图过大会采用DFS算法递归方式的大量递归函数调用会导致用户程序递归栈溢出而导致时间过长或者运行时错误,可以在程序中开栈代替递归(所有的递归房事都可以用栈来实现为非递归方式),或者采用基于队列的BFS算法,能够避免大量的递归调用造成的初始化局部变量、分配内存等时空开销。
由于博主水平有限,不免有疏漏之处,欢迎读者随时批评指正,以免造成不必要的误解!
发布评论