Depth First Search (DFS) | Iterative & Recursive Implementation
来源:互联网 发布:网络营运商 编辑:程序博客网 时间:2024/05/21 19:34
深度优先搜索(DFS)|迭代和递归实现
深度优先搜索(DFS)是一种用于遍历或搜索树或图形数据结构的算法。一个从根开始(在图形的情况下选择一些任意节点作为根),并且在回溯之前尽可能沿着每个分支进行探索。
下图显示了在DFS中发现节点的顺序
深度首先在树中搜索
树是一个无向图,其中任何两个顶点通过一个路径连接。换句话说,任何非循环连接图是一棵树。对于树,我们有以下遍历方法 -
preorder:访问其子节点前的每个节点。
postorder:访问每个节点后的孩子。
inorder(仅适用于二叉树):访问左子树,节点,右子树。
深度在图中首先搜索
深度优先搜索是一种遍历图形的方式,这与树的预订遍历密切相关。以下是预订遍历的递归执行:
procedure preorder(treeNode v){ visit(v); for each child u of v preorder(u);}
为了将其转换为图形遍历算法,我们基本上将“child”替换为“neighbor”。但是为了防止无限循环,我们跟踪顶点已经被发现,而不再访问它们。
procedure dfs(vertex v){ visit(v); for each neighbor u of v if u is undiscovered call dfs(u);}
C ++实现 -
include <bits/stdc++.h> using namespace std; //图中的顶点数 #define N 13 //数据结构存储图形边 struct Edge { int src, dest; }; //类来表示一个图形对象 class Graph { public: //表示相邻列表的向量数组 vector<int> adjList[N]; //构造函数 Graph(vector<Edge> edges) { //将边缘添加到无向图 for (int i = 0; i < edges.size(); i++) { int src = edges[i].src; int dest = edges[i].dest; adjList[src].push_back(dest); adjList[dest].push_back(src); } } }; //执行DFS遍历的功能 int DFS(Graph const &graph, int v, vector<bool> &discovered) { //将当前节点标记为已发现 discovered[v] = true; //打印当前节点 cout << v << " "; //为每个边缘做(v - > u) for (int u : graph.adjList[v]) { //u没有发现 if (!discovered[u]) DFS(graph, u, discovered); } } // 主功能 int main() { //如上图所示的图形边沿向量 vector<Edge> edges = { {1, 2}, {1, 7}, {1, 8}, {2, 3}, {2, 6}, {3, 4}, {3, 5}, {8, 9}, {8, 12}, {9, 10}, {9, 11} }; //从给定的边缘创建图形 Graph graph(edges); //存储顶点是否被发现 vector<bool> discovered(N); //将DFS从所有未发现的节点遍历到 //覆盖图形的所有未连接的组件 for (int i = 1; i < N; i++) if (discovered[i] == false) DFS(graph, i, discovered); return 0; }
输出:
1 2 3 4 5 6 7 8 9 10 11 12
DFS遍历的时间复杂度为O(n + m),其中n为顶点数,e为图中边缘数。请注意,O(m)可能在O(1)和O(n2)之间变化,具体取决于图形的密度。
DFS的应用 -
在图中查找连接的组件
DAG中的拓扑排序(定向非循环图)
查找2-(边缘或顶点)连接的组件。
查找3-(边缘或顶点)连接的组件。
找到一个图表的桥梁。
查找强连接的组件。
解决谜题只有一个解决方案,如迷宫。
在图表中找到双连通性等等。
非递归执行DFS
DFS的非递归实现类似于BFS的非递归实现,但与两种方式不同:
它使用堆栈而不是队列
只有在弹出顶点之后,DFS才能标记发现。
它使用反向迭代器而不是迭代器来产生与递归DFS相同的结果。
C ++实现 -
#include <bits/stdc++.h> using namespace std; //图中的顶点数 #define N 13 //数据结构存储图形边 struct Edge { int src, dest; }; //类来表示一个图形对象 class Graph { public: //表示相邻列表的向量数组 vector<int> adjList[N]; //构造函数 Graph(vector<Edge> edges) { //将边缘添加到无向图 for (int i = 0; i < edges.size(); i++) { int src = edges[i].src; int dest = edges[i].dest; adjList[src].push_back(dest); adjList[dest].push_back(src); } } }; //从顶点v开始,在图g上执行迭代DFS int iterativeDFS(Graph const &graph, int v) { //存储顶点是否被发现 vector<bool> discovered(N); //创建一个用于执行迭代DFS的堆栈 stack<int> stack; //将源节点推入堆栈 stack.push(v); //运行到堆栈不是空的 while (!stack.empty()) { //从堆栈中弹出一个顶点 v = stack.top(); stack.pop(); //如果顶点已经被发现了, // 忽略它 if (discovered[v]) continue; //如果弹出的顶点v //尚未发现。我们打印并处理 //其未发现的相邻节点进入堆栈 discovered[v] = true; cout << v << " "; //为每个边缘做(v - > u) //我们使用反向迭代器(为什么?) for (auto it = graph.adjList[v].rbegin(); it != graph.adjList[v].rend(); ++it) { int u = *it; if (!discovered[u]) stack.push(u); } } } // 主功能 int main() { //如上图所示的图形边沿向量 vector<Edge> edges = { {1, 2}, {1, 7}, {1, 8}, {2, 3}, {2, 6}, {3, 4}, {3, 5}, {8, 9}, {8, 12}, {9, 10}, {9, 11} // , {6, 9} //介绍循环 }; //从给定的边缘创建图形 Graph graph(edges); //从顶点1执行迭代DFS遍历 iterativeDFS(graph, 1); return 0; }
输出:
1 2 3 4 5 6 7 8 9 10 11 12
阅读全文
0 0
- Depth First Search (DFS) | Iterative & Recursive Implementation
- Breadth First Search (BFS) | Iterative & Recursive Implementation
- Non recursive Depth first search
- DFS(Depth-First-Search)
- NYU AI作业习题-活动安排问题 BFS+DFS Iterative deepening depth-first search
- Recursive Depth first search graph(adj matrix)
- Depth First Search (DFS)入门
- Tree-DFS(Depth-First-Search)
- IDDFS(Iterative deepening depth-first search)的Java实现
- Depth-First-Search(DFS伪代码)
- 经典dfs(depth-first search)
- 深度优先搜索(Depth-First-Search,DFS)
- 深度优先搜索Depth-first search (DFS) for undirected graphs
- DFS --- Depth First Search 深度优先搜索算法
- 深度优先搜索DFS(depth first search),拓扑排序
- 图的深度优先搜索(Depth First Search,DFS)
- 利用DFS拆分数系列;Depth First Search
- 5.3.2 深度优先搜索(Depth-First-Search,DFS)
- git和SVN的区别
- 平时一些程序杂记
- MySQL 5.6 (Win7 64位)下载、安装与配置图文教程
- PAT 1023组个最小数
- CodeForces 359 D.Pair of Numbers (二分+ST)
- Depth First Search (DFS) | Iterative & Recursive Implementation
- 数据采集(二):腾讯新闻网,新闻标题和内容爬取
- java.concurrent包常见类详解
- 主流手机分辨率
- 前端布局之Flex语法
- JVM的内存模型
- 微服务的优缺点
- centos 配置php环境-apache,mysql5.6,php5.6环境过程分享
- linux之sed的用法