Java实现图深度优先搜索与路径查找算法详解

小满
小满
发布时间:2026-10-15| 5人浏览过
原创

本文介绍如何利用Java结合深度优先搜索(DFS)解决图中的路径查找问题。通过edgeTo数组记录前驱节点,可以准确还原从起点到任意可达顶点的路径,适合用于导航规划、连通性检测等场景。

路径查找的实际意义

在现实应用中,例如地图导航系统输入出发地与目的地,系统需规划出一条可通行的路线。这类需求映射为计算机科学中的经典图论问题:给定无向图 G 的起点 s 和终点 v,如何判定是否存在一条连接两点的边序列?若存在,请将其完整输出。

如图所示,寻找从顶点 0 到达顶点 4 的路径。图中红色标识的连接方式即为有效路径,其顶点序列表示为 0-2-3-4。

算法核心原理:深度优先搜索

要实现路径查找,必须对图进行系统性遍历。我们选择基于深度优先搜索(Depth-First Search, DFS)来实现该功能,其基本逻辑是尽可能深地搜索树的分支。

与普通 DFS 仅标记是否访问过不同,我们需要额外维护一个整数数组 edgeTo[]。该数组用于记录从起点 s 到达当前顶点时,上一步所在的顶点编号。当递归回溯或终止时,我们可以顺着 edgeTo 倒推,从而重建整条路径。

假设设定起点 s 为 0,搜索过程如下:

工作原理总结:
edgeTo 数组的下标代表目标顶点,存储的值代表该顶点在到达前经过的最后一个顶点(即父节点)。一旦搜索完成,查询从起点 0 到任意顶点 v 的路径变得非常直观。

类设计与实现步骤

第1步:确定 API 设计

在设计类之前,明确需要管理的成员变量及对外提供的操作方法:

类型详细说明
成员变量
  • private boolean[] marked:布尔数组,索引为顶点ID,值为该顶点是否已被搜索过。
  • private int s:记录当前搜索的起点顶点。
  • private int[] edgeTo:整型数组,索引为顶点ID,值记录从起点到达该顶点的“上一个”顶点,用于还原路径。
构造方法public DepthFirstPaths(Graph G, int s):接收图对象 G 与起点 s,在初始化阶段执行一次深度优先搜索以计算所有路径信息。
成员方法
  • private void dfs(Graph G, int v):私有递归方法,从顶点 v 出发继续向其邻居搜索。
  • public boolean hasPathTo(int v):公开接口,判断顶点 v 是否与起点 s 相连通。
  • public Stack pathTo(int v):公开接口,若存在路径,则返回由起点到终点的所有顶点组成的栈结构。

第2步:编写路径查找核心代码

以下是完整的 DepthFirstPaths Java 实现。代码包含详细的注释,展示了数组初始化、递归遍历以及路径还原的逻辑:

/**
 * 图的路径查找类 (基于深度优先搜索)
 */
public class DepthFirstPaths {
    // 索引代表顶点,值表示当前顶点是否已经被搜索
    private boolean[] marked;
    // 记录起点
    private int s;
    // 索引代表顶点,值代表从起点s到当前顶点路径上的上一个顶点
    private int[] edgeTo;

    /**
     * 构造深度优先搜索对象
     * @param G 图对象
     * @param s 起点顶点编号
     */
    public DepthFirstPaths(Graph G, int s){
        // 根据图的顶点总数初始化标记数组
        this.marked = new boolean[G.V()];
        // 记录起点
        this.s = s;
        // 初始化路径追踪数组
        this.edgeTo = new int[G.V()];

        // 执行深度优先搜索填充数据
        dfs(G, s);
    }

    /**
     * 使用深度优先搜索找出G图中v顶点的所有相邻顶点
     */
    private void dfs(Graph G, int v){
        // 标记当前顶点v为已搜索
        marked[v] = true;

        // 遍历顶点v的邻接表,获取每一个相邻的顶点w,继续递归
        for (Integer w : G.adj(v)) {
            // 如果顶点w尚未被搜索过,则确立路径关系并深入搜索
            if (!marked[w]){
                // 记录:到达顶点w的前一个节点是v
                edgeTo[w] = v;
                dfs(G, w);
            }
        }
    }

    /**
     * 判断顶点w与起点s之间是否存在路径
     */
    public boolean hasPathTo(int v){
        return marked[v];
    }

    /**
     * 找出从起点s到顶点v的路径
     * @return 路径上的顶点栈,若无路径则返回null
     */
    public Stack<Integer> pathTo(int v){
        // 如果不可达,直接返回空
        if (!hasPathTo(v)){
            return null;
        }

        // 创建栈对象,用于逆向收集路径中的所有顶点
        Stack<Integer> path = new Stack<>();

        // 利用edgeTo数组,从顶点v开始向前回溯,直到回到起点s
        for (int x = v; x != s; x = edgeTo[x]){
            path.push(x);
        }

        // 将起点也压入栈底
        path.push(s);

        // 此时栈顶是起点,出栈顺序即为从起点到终点的路径
        return path;
    }
}
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。