算法7-3:深度优先搜索

深度优先搜索最初是因为迷宫游戏而诞生的。在一个迷宫中,有一个入口和一个出口,其中只有一条路径能从入口到达出口。在走迷宫的时候,每次将走过的地方进行标记,遇到死胡同的时候可以沿着进来的路线后退,找到新的没走过的拐角再尝试新的路线。这种方法的效率很高,因为每个地方只需要走过一次即可。其实,这就是深度优先搜索。

深度优先搜索的目标就是系统化地遍历整个图,让算法的效率更高。

应用

深度优先搜索有几个非常典型的应用:

  • 找出源顶点能到达的所有顶点
  • 找出两个顶点之间的路径
  • 判断两个顶点是否连通

基本思想

深度优先搜索的步骤如下:

  1. 将v标记为已拜访
  2. 迭代拜访与v相邻的没有拜访过的所有顶点

设计模式

和图论有关的算法非常多,相应的数据结构也非常多。那么,为了不让Graph这个类变得太复杂,所以需要将图论的算法放在另外一个单独的对象中,这样两个类之间的耦合度低一些,编码的时候也会更加好用。因此在后续的章节中都会采用这样的设计模式,使得每个算法都会有一个单独的类。

代码

import java.util.Stack;

/**
 * Created by caipeichao on 14-6-10.
 */
public class DFS {
    private boolean[] visited;
    private int[] edgeTo;
    private int s;

    /**
     * @param G 图
     * @param s 遍历的起点
     */
    public DFS(Graph G, int s) {
        this.s = s;

        // 所有的顶点都没有访问过
        visited = new boolean[G.V()];

        // 从哪个顶点来的?
        edgeTo = new int[G.V()];

        // 开始深搜
        dfs(G, s);
    }

    private void dfs(Graph G, int v) {
        visited[v] = true;
        for (int w : G.adj(v)) {
            if (!visited[w]) {
                edgeTo[w] = v;
                dfs(G, w);
            }
        }
    }

    public boolean hasPathTo(int v) {
        return visited[v];
    }

    public Iterable<Integer> pathTo(int v) {
        if(!hasPathTo(v)) return null; // 注意:这句话不要忘记了
        Stack<Integer> result = new Stack<Integer>();
        while (v != s) { // 注意:到达源点的时候就应该退出循环
            result.add(v);
            v = edgeTo[v];
        }
        return result;
    }
}

复杂度

简单地说复杂度和参与运算的边数成正比。所谓参与运算的边就是指源点能到达的边。

算法7-3:深度优先搜索,布布扣,bubuko.com

时间: 2024-10-25 22:36:43

算法7-3:深度优先搜索的相关文章

【算法入门】深度优先搜索(DFS)

深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 你可以跳过第二节先看第三节,:) 2.深度优先搜索VS广度优先搜索 2.1演示深度优先搜索的过程还是引用上篇文章的样例图,起点仍然是V0,我们修改一下题目意思,只需要让你找出一条V0到V6的道路,而无需最短

算法导论——DFS深度优先搜索

package org.loda.graph; import org.loda.structure.Stack; /** * * @ClassName: DFS * @Description: 深度优先搜索(无向图) * @author minjun * @date 2015年5月24日 上午4:02:24 * */ public class DFS { //原点 private int s; // visited[i]表示i节点是否被访问过 private boolean[] visited;

小橙书阅读指南(十二)——无向图、深度优先搜索和路径查找算法

在计算机应用中,我们把一系列相连接的节点组成的数据结构,叫做图.今天我们将要介绍它的一种形式--无向图,以及针对这种结构的深度优先搜索和路径查找算法. 一.无向图数据结构 接口: /** * 图论接口 */ public interface Graph { /** * 顶点数 * * @return */ int vertexNum(); /** * 边数 * * @return */ int edgeNum(); /** * 向图中添加一条v-w的边 * * @param v * @param

深度优先搜索-linux上浅显易懂的例子

上次看啊哈算法中的深度优先搜索,自己用的是linux(linux粉,windows黑,嘿嘿),字符界面,为了强化对这个的理解,就在linux上对这个例子的代码做了一点修改可以很清楚的看到整个搜索过程,相当于动态的展示吧,虽然不是动画,本来想用QT来写的,不过实在是没时间(其实是QT太久没用了.....) 深度优先搜索说到底就是一条道走到黑直到达到目的,然后再往回走,看看上次选择的地方是否还有别的路可以选择走.代码中定义了宏MAX_NUM=8, 就是8x8的迷宫, 用户输入开始点和结束点,找到开始

深度优先搜索检测有向图有无环路算法

给定有向图 G = (V, E),需要判断该图中是否存在环路(Cycle).例如,下面的图 G 中包含 4 个顶点和 6 条边. 实际上,上图中存在 3 个环路:0->2->0, 0->1->2->0, 3->3. 深度优先搜索(DFS:Depth-First Search)可以用于检测图中是否存在环.DFS 会对一个连通的图构造一颗树,如果在构造树的过程中出现反向边(Back Edge),则认为图中存在环路. 对于非连通图,可以对图中的不同部分分别进行 DFS 构造树

&quot;《算法导论》之‘图’&quot;:深度优先搜索、宽度优先搜索及连通分量

本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步.  1. 深度优先搜索  1.1 迷宫搜索 在<算法>这本书中,作者写了很好的一个故事.这个故事让我马上理解了深度优先搜索的思想. 如下图1-1所示,如何在这个迷宫中找到出路呢?方法见图1-2. 图1-1 等价的迷宫模型 探索迷宫而不迷路的一种古老办法(至少可以追溯到忒修斯和米诺陶的传说)叫做Tremaux搜

算法导论22.3深度优先搜索 练习总结 (转载)

22.3-1 画一个 3*3 的网格,行和列的抬头分别标记为白色.灰色和黑色,对于每个表单元 (i, j),请指出对有向图进行深度优先搜索的过程中,是否可能存在一条边,链接一个颜色为 i 的结点和一个颜色为 j 的结点.对于每种可能的边,指明该种边的类型.另外,请针对无向图的深度优先搜索再制作一张这样的网格. ANSWER:   22.3-2 给出深度优先搜索算法在图 22-6 上的运行过程.假定深度优先搜索算法的第 5~7 行的 for 循环是以字母表顺序依次处理每个结点,假定每条邻接链表皆以

代码与算法集锦-归并排序+树状数组+快排+深度优先搜索+01背包(动态规划)

归并排序 求逆序数 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 首先考虑下如何将将二个有序数列合并.这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数.然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可. //将有序数组a[]和b[]合并到c[]中 void MemeryArray(int a[], int n, int b[], int m, int c

十大基础实用算法之深度优先搜索和广度优先搜索

深度优先搜索算法(Depth-First-Search),是搜索算法的一种.它沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止.DFS属于盲目搜索. 深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相