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. Unity shader学习之Forward Rendering Path

    Forward rendering path shader如下: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObje ...

  2. python2.7之乱码问题

    python 3之后当然不存在乱码问题了.python 2的乱码问题有时就有点头疼了.(代码均为在windows下测试) 示例:保存为test1.py 报错信息如下: 解决办法: 我将代码保存为tes ...

  3. I Count Tow Three

    #include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#inclu ...

  4. kali长时间未使用导致数字签名过期无法更新源解决办法

    kali长时间未使用,数字签名会过期,从而导致无法更新源. apt-get update:从源(Source)服务器那里下载最新的软件包列: apt-get upgrade:对已经安装的软件包本身进行 ...

  5. npm 代理的设置和取消

    管理员权限下的控制台输入: 设置代理 npm config set proxy=http://127.0.0.1:8080 npm config set registry=http://registr ...

  6. Spring boot jackson

    Spring boot 所引用的包里面包含 jackson-databind-2.8.3.jar jackson-annotations-2.8.3.jar jackson-core-2.8.3.ja ...

  7. spring 源码导入eclipse(sts)

    一. 准备工作 1.下载安装sts(springsource推荐使用) 下载地址: http://www.springsource.org/downloads/sts-ggts 2.下载安装gradl ...

  8. python 测试文件或者文件目录是否存在 测试文件类型,获取文件大小,获取修改日期

    ----测试一个文件或目录是否存在 >>> import os >>> os.path.exists('/etc/passwd') True >>> ...

  9. 那些年 Qzone

    那些年转在Qzone里的: 不喊痛,不一定没感觉.不要求,不一定没期待.不落泪,不一定没伤痕.不说话,不一定没心声.沉默,不代表自己没话说.离开,不代表自己很潇洒.快乐,不代表自己没伤心.幸福,不代表 ...

  10. AdminLTE模板使用

    AdminLTE介绍: AdminLTE是一款建立在bootstrap和jquery之上的开源的模板主题工具,它提供了一系列响应的,可重复使用的组件,并内置了多个模板页面;同时自适应多种屏幕分辨率,兼 ...