Depth-first search

Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures.

The algorithm starts at the root node (selecting some arbitrary node as the root node in the case of a graph) and explores as far as possible along each branch before backtracking 回溯.

For the following graph:

a depth-first search starting at A,

assuming that the left edges in the shown graph are chosen before right edges,

and assuming the search remembers previously visited nodes and will not repeat them (since this is a small graph),

will visit the nodes in the following order: A, B, D, F, E, C, G.

The edges traversed in this search form a Trémaux tree, a structure with important applications in graph theory.

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A, B, D, F, E, A, B, D, F, E, etc. forever, caught in the A, B, D, F, E cycle and never reaching C or G.

Iterative deepening is one technique to avoid this infinite loop and would reach all nodes.

深度优先的算法实现

Input: A graph G and a vertex v of G

Output: All vertices reachable from v labeled as discovered

A recursive implementation of DFS:[5]

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

The order in which the vertices are discovered by this algorithm is called the lexicographic order.

A non-recursive implementation of DFS with worst-case space complexity O(|E|):[6]  (使用栈,先进后出)

1  procedure DFS-iterative(G,v):
2 let S be a stack
3 S.push(v)
4 while S is not empty
5 v = S.pop()
6 if v is not labeled as discovered:
7 label v as discovered
8 for all edges from v to w in G.adjacentEdges(v) do
9 S.push(w)

These two variations of DFS visit the neighbors of each vertex in the opposite order from each other: the first neighbor of v visited by the recursive variation is the first one in the list of adjacent edges, while in the iterative variation the first visited neighbor is the last one in the list of adjacent edges. The recursive implementation will visit the nodes from the example graph in the following order: A, B, D, F, E, C, G. The non-recursive implementation will visit the nodes as: A, E, F, B, D, C, G.

The non-recursive implementation is similar to breadth-first search but differs from it in two ways:

  1. it uses a stack instead of a queue, and
  2. it delays checking whether a vertex has been discovered until the vertex is popped from the stack rather than making this check before adding the vertex.

Breadth-first search

Breadth-first search (BFS) is an algorithm for traversing or searching tree or graph data structures.

It starts at the tree root (or some arbitrary node of a graph, sometimes referred to as a 'search key'[1]), and explores all of the neighbor nodes at the present depth prior to moving on to the nodes at the next depth level.

It uses the opposite strategy as depth-first search, which instead explores the highest-depth nodes first before being forced to backtrack回溯 and expand shallower nodes.

shallower是shallow的比较级,较浅的

广度优先的实现  (使用队列,先进先出)

Input: A graph Graph and a starting vertex顶点 root of Graph

Output: Goal state. The parent links trace the shortest path back to root

1  procedure BFS(G,start_v):
2 let S be a queue
3 S.enqueue(start_v)
4 while S is not empty
5 v = S.dequeue()
6 if v is the goal:
7 return v
8 for all edges from v to w in G.adjacentEdges(v) do
9 if w is not labeled as discovered:
10 label w as discovered
11 w.parent = v
12 S.enqueue(w)

More details

This non-recursive implementation is similar to the non-recursive implementation of depth-first search, but differs from it in two ways:

  1. it uses a queue (First In First Out) instead of a stack and
  2. it checks whether a vertex顶点 has been discovered before enqueueing the vertex rather than delaying this check until the vertex is dequeued from the queue.

The Q queue contains the frontier along which the algorithm is currently searching.

Nodes can be labelled as discovered by storing them in a set, or by an attribute on each node, depending on the implementation.

Note that the word node is usually interchangeable with the word vertex.

The parent attribute of each vertex is useful for accessing the nodes in a shortest path, for example by backtracking from the destination node up to the starting node, once the BFS has been run, and the predecessors nodes have been set.

Breadth-first search produces a so-called breadth first tree. You can see how a breadth first tree looks in the following example.

Depth-first search and Breadth-first search 深度优先搜索和广度优先搜索的更多相关文章

  1. DFS_BFS(深度优先搜索 和 广度优先搜索)

    package com.rao.graph; import java.util.LinkedList; /** * @author Srao * @className BFS_DFS * @date ...

  2. 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法

    Graph Search and Connectivity Generic Graph Search Goals 1. find everything findable 2. don't explor ...

  3. 【js数据结构】图的深度优先搜索与广度优先搜索

    图类的构建 function Graph(v) {this.vertices = v;this.edges = 0;this.adj = []; for (var i = 0; i < this ...

  4. DFS或BFS(深度优先搜索或广度优先搜索遍历无向图)-04-无向图-岛屿数量

    给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 1: 输入: ...

  5. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  6. 深度优先搜索(DFS)和广度优先搜索(BFS)

    深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...

  7. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

  8. Unity中通过深度优先算法和广度优先算法打印游戏物体名

    前言:又是一个月没写博客了,每次下班都懒得写,觉得浪费时间.... 深度优先搜索和广度优先搜索的定义,网络上已经说的很清楚了,我也是看了网上的才懂的,所以就不在这里赘述了.今天讲解的实例,主要是通过自 ...

  9. 广度优先搜索(Breadth First Search, BFS)

    广度优先搜索(Breadth First Search, BFS) BFS算法实现的一般思路为: // BFS void BFS(int s){ queue<int> q; // 定义一个 ...

随机推荐

  1. windows下配置lua环境

    1.进入lua官网http://www.lua.org/ 2.点击download 3.点击get a binary 4.点击[Lua - joedf's Builds] 5.选择适合自己的版本下载, ...

  2. Properties (25)

    1.Properties 没有泛型.也是哈希表集合,无序集合.{a=1,b=2,c=3}   2. 读取文件中的数据,并保存到集合   (Properties方法:stringPropertyName ...

  3. javascript实现异步编程的4种方法

    1.回调函数. 2.事件监听 .  思路:采用事件驱动模式.任务的执行不取决于代码的顺序,而取决于某个事件是否发生 3.观察者模式 (发布/订阅模式)   代码如下: jQuery.subscribe ...

  4. mybatis源码解析7---MappedStatement初始化过程

    上一篇我们了解到了MappedStatement类就是mapper.xml中的一个sql语句,而Configuration初始化的时候会加载所有的mapper接口类,而本篇再分析下是如何将mapper ...

  5. 浅析PAC,修改PAC文件及user-rule文件实现自动代理

    浅析PAC,修改PAC文件及user-rule文件实现自动代理 代理自动配置(英语:Proxy auto-config,简称PAC)是一种网页浏览器技术,用于定义浏览器该如何自动选择适当的代理服务器来 ...

  6. HDU 1233 还是畅通工程 (最小生成树 )

    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路 ...

  7. jdbc连接oracle数据库问题

    下面是JDBC连接oracle数据库流程: String dbURL = "jdbc:oracle:thin:@url:1521:service_name"; String use ...

  8. SOAPUI 案例操作步骤

    1. 构建项目 2. 运行单个请求 3. 构建测试用例 4. 接口之间传递参数 5. 运行整个测试用例 构建测试 以天气接口为例: 接口: http://ws.webxml.com.cn/WebSer ...

  9. 怎样从外网访问内网RESTful API?

    本地部署了RESTful API,只能在局域网内访问,怎样从外网也能访问到本地的RESTful API呢?本文将介绍具体的实现步骤. 准备工作 部署并启动RESTful API服务端 默认部署的RES ...

  10. Q_DECL_OVERRIDE

    Q_DECL_OVERRIDE也就是c++的override # define Q_DECL_OVERRIDE override 在重写虚函数时会用到, 作用是防止写错虚函数: void keyPre ...