There are generally two methods to write DFS algorithm, one is using recursion, another one is using stack. (reference from Wiki Pedia)

Pseudocode for both methods:

A recursive implementation of DFS:

 procedure DFS(G,v):
label v as discovered
for all edges from v to w in G.adjacentEdges(v) do
if vertex w is not labeled as discovered then
recursively call DFS(G,w)

A non-recursive implementation of DFS(using stack):

   procedure DFS-iterative(G,v):
let S be a stack
S.push(v)
while S is not empty
v ← S.pop()
if v is not labeled as discovered:
label v as discovered
for all edges from v to w in G.adjacentEdges(v) do
S.push(w)

The non-recursive implementation is similar to breadth-first search but differs from it in two ways: it uses a stack instead of a queue, and it delays checking whether a vertex has been discovered until the vertex is popped from the stack rather than making this check before pushing the vertex.

Here's another good explenation: http://www.algolist.net/Algorithms/Graph/Undirected/Depth-first_search

Depth-first search, or DFS, is a way to traverse the graph. Initially it allows visiting vertices of the graph only, but there are hundreds of algorithms for graphs, which are based on DFS. Therefore, understanding the principles of depth-first search is quite important to move ahead into the graph theory. The principle of the algorithm is quite simple: to go forward (in depth) while there is such possibility, otherwise to backtrack.

Algorithm

In DFS, each vertex has three possible colors representing its state:

white: vertex is unvisited;

gray: vertex is in progress;

black: DFS has finished processing the vertex.

NB. For most algorithms boolean classification unvisited / visited is quite enough, but we show general case here.

Initially all vertices are white (unvisited). DFS starts in arbitrary vertex and runs as follows:

  1. Mark vertex u as gray (visited).
  2. For each edge (u, v), where u is white, run depth-first search for u recursively.
  3. Mark vertex u as black and backtrack to the parent.

Example. Traverse a graph shown below, using DFS. Start from a vertex with number 1.

Source graph.
Mark a vertex 1 as gray.
There is an edge (1, 4) and a vertex 4 is unvisited. Go there.
Mark the vertex 4 as gray.
There is an edge (4, 2) and vertex a 2 is unvisited. Go there.
Mark the vertex 2 as gray.
There is an edge (2, 5) and a vertex 5 is unvisited. Go there.
Mark the vertex 5 as gray.
There is an edge (5, 3) and a vertex is unvisited. Go there.
Mark the vertex 3 as gray.
There are no ways to go from the vertex 3. Mark it as black and backtrack to the vertex 5.
There is an edge (5, 4), but the vertex 4 is gray.
There are no ways to go from the vertex 5. Mark it as black and backtrack to the vertex 2.
There are no more edges, adjacent to vertex 2. Mark it as black and backtrack to the vertex 4.
There is an edge (4, 5), but the vertex 5 is black.
There are no more edges, adjacent to the vertex 4. Mark it as black and backtrack to the vertex 1.
There are no more edges, adjacent to the vertex 1. Mark it as black. DFS is over.


Complexity analysis
If a graph is disconnected, DFS won't visit all of its vertices. For details, see finding connected components algorithm.As you can see from the example, DFS doesn't go through all edges. The vertices and edges, which depth-first search has visited is a tree. This tree contains all vertices of the graph (if it is connected) and is called graph spanning tree. This tree exactly corresponds to the recursive calls of DFS.

Assume that graph is connected. Depth-first search visits every vertex in the graph and checks every edge its edge. Therefore, DFS complexity is O(V + E). As it was mentioned before, if an adjacency matrix is used for a graph representation, then all edges, adjacent to a vertex can't be found efficiently, that results in O(V2)complexity. You can find strong proof of the DFS complexity issues in [1].

Java Implementation

 public class Graph {
… enum VertexState {
White, Gray, Black
} public void DFS()
{
VertexState state[] = new VertexState[vertexCount];
for (int i = 0; i < vertexCount; i++)
state[i] = VertexState.White;
runDFS(0, state);
} public void runDFS(int u, VertexState[] state)
{
state[u] = VertexState.Gray;
for (int v = 0; v < vertexCount; v++)
if (isEdge(u, v) && state[v] == VertexState.White)
runDFS(v, state);
state[u] = VertexState.Black;
}
}

Summary: Depth-first Search(DFS)的更多相关文章

  1. [Algorithm] Write a Depth First Search Algorithm for Graphs in JavaScript

    Depth first search is a graph search algorithm that starts at one node and uses recursion to travel ...

  2. [算法&数据结构]深度优先搜索(Depth First Search)

    深度优先 搜索(DFS, Depth First Search) 从一个顶点v出发,首先将v标记为已遍历的顶点,然后选择一个邻接于v的尚未遍历的顶点u,如果u不存在,本次搜素终止.如果u存在,那么从u ...

  3. 幸运的袋子(深度优先遍历(Depth First Search,DFS))

    题目描述 一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的).如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积. 例如:如果袋子里面的球的号码是{1, 1, 2 ...

  4. Non recursive Depth first search

    深度优先非递归实现算法: 1 递归算法: //初始化相关数据结构 DFS(G) ------------------------------------------------------------ ...

  5. Recursive Depth first search graph(adj matrix)

    1 深度优先遍历邻接矩阵 1 邻接矩阵初始化 2 访问数组初始化 3 深度优先遍历邻接矩阵图 算法如下: bool MGraph[128][128]; bool visit[128]; int vex ...

  6. 深度优先搜索(Depth First Search)

    Date:2019-07-01 15:31:11 通俗点理解就是不撞南墙不回头的那种,用栈来实现 算法实现 /* 题目描述: 有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物 ...

  7. 深度优先搜索 DFS(Depath First Search, DFS)

    深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法.(不撞南墙不回头) DFS一般用递归来实现,其伪代码思路过程一般如下: void DFS(必要的参数){    if (符和遍历到一条完整路 ...

  8. [MIT6.006] 14. Depth-First Search (DFS), Topological Sort 深度优先搜索,拓扑排序

    一.深度优先搜索 它的定义是:递归探索图,必要时要回溯,同时避免重复. 关于深度优先搜索的伪代码如下: 左边DFS-Visit(V, Adj.s)是只实现visit所有连接某个特定点(例如s)的其他点 ...

  9. 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)

    数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...

随机推荐

  1. 题目1456:胜利大逃亡(广度优先搜索BFS)

    题目链接:http://ac.jobdu.com/problem.php?pid=1456 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  2. sencha touch list ListPaging使用详解

    示例代码: Ext.define('app.view.message.List', { alternateClassName: 'messageList', extend: 'Ext.List', x ...

  3. 去掉VS2010代码中文注释的红色下划线

    VS2010代码中文注释出现红色下划线,代码看上去很不美观,发现是由于安装Visual Assist X插件造成的. 解决办法:打开VAX的Options对话框,取消Advanced --> U ...

  4. python pytest测试框架介绍一

    一.安装 pytest不是python默认的package,需要自动手工安装. pytest支持python 2.6--3.5之间的版本,同时可以在unix及windows上安装 安装方式: pip ...

  5. Unity3D NGUI 二 NGUI Button怎样接受用户点击并调用函数,具体方法名称是什么

    a.直接监听事件 把下面脚本直接绑定在按钮上,当按钮点击时就可以监听到,这种方法不太好很不灵活. void OnClick(){ Debug.Log("Button is Click!!!& ...

  6. 【Win】使用L2TP出现809错误

    1.环境:win7/10 2.解决: a.修改注册表(新建一个文本文件,复制以下内容,保存后文件扩展名改为.reg,双击运行文件.) Windows Registry Editor Version 5 ...

  7. codeforces#518 Div2 ABCDE

    A---Birthday http://codeforces.com/contest/1068/problem/A 题意: 有n种硬币,m个人.m个人要给Ivan送硬币,每个人送的硬币都要互不相同但数 ...

  8. ubuntu16.04下安装ros-kinetic

    参考:http://wiki.ros.org/kinetic/Installation/Ubuntu 1.添加ROS软件源 ~$ sudo sh -c 'echo "deb http://p ...

  9. chrome Sources选项卡 设置JavaScript事件断点

    chrome console 可以查看执行的javascript么? 举个例子: 比如这张图片,163邮箱,我点击上一封邮件和下一封邮件执行的是javascript方法. 虽然在chrome的cons ...

  10. Myers–Briggs_Type_Indicator 迈尔斯布里格斯类型指标(MBTI)

    Myers–Briggs Type Indicator - Wikipedia https://en.wikipedia.org/wiki/Myers%E2%80%93Briggs_Type_Indi ...