首页 > 代码库 > 算法7-3:深度优先搜索
算法7-3:深度优先搜索
深度优先搜索最初是因为迷宫游戏而诞生的。在一个迷宫中,有一个入口和一个出口,其中只有一条路径能从入口到达出口。在走迷宫的时候,每次将走过的地方进行标记,遇到死胡同的时候可以沿着进来的路线后退,找到新的没走过的拐角再尝试新的路线。这种方法的效率很高,因为每个地方只需要走过一次即可。其实,这就是深度优先搜索。
深度优先搜索的目标就是系统化地遍历整个图,让算法的效率更高。
应用
深度优先搜索有几个非常典型的应用:
找出源顶点能到达的所有顶点
找出两个顶点之间的路径
判断两个顶点是否连通
基本思想
深度优先搜索的步骤如下:
将v标记为已拜访
迭代拜访与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; } }
复杂度
简单地说复杂度和参与运算的边数成正比。所谓参与运算的边就是指源点能到达的边。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。