讲师中心 微信公众号
AI工具推荐 视频效率加速

如何用Java实现图的遍历 Java图的DFS和BFS算法示例

胖芳吖_4475

胖芳吖_4475

发布时间:2025-07-19 11:17:01

|

362人浏览过

|

来源于php中文网

原创

图的遍历主要有深度优先搜索(dfs)和广度优先搜索(bfs)两种算法。1.dfs使用栈结构,适合路径查找、连通性检测等场景;2.bfs使用队列结构,适合最短路径查找、网络爬虫等场景。两者均需通过visited数组避免重复访问。此外,还有dijkstra、a*、floyd-warshall、拓扑排序等其他图遍历或相关算法,适用于不同需求。性能优化包括使用邻接表存储、避免重复访问、迭代代替递归、并行化处理等。应用场景涵盖社交网络分析、路径查找、推荐系统、编译器、垃圾回收等多个领域。

如何用Java实现图的遍历 Java图的DFS和BFS算法示例

图的遍历,简单来说,就是系统地访问图中的每一个顶点,而且每个顶点只访问一次。Java实现图的遍历主要依赖两种算法:深度优先搜索(DFS)和广度优先搜索(BFS)。它们各有特点,适用于不同的场景。

如何用Java实现图的遍历 Java图的DFS和BFS算法示例
import java.util.*;

class Graph {
    private int vertices;
    private LinkedList<Integer>[] adjList;

    Graph(int vertices) {
        this.vertices = vertices;
        adjList = new LinkedList[vertices];
        for (int i = 0; i < vertices; i++) {
            adjList[i] = new LinkedList<>();
        }
    }

    void addEdge(int src, int dest) {
        adjList[src].add(dest);
    }

    // DFS 算法
    void DFS(int startVertex) {
        boolean[] visited = new boolean[vertices];
        DFSUtil(startVertex, visited);
    }

    private void DFSUtil(int vertex, boolean[] visited) {
        visited[vertex] = true;
        System.out.print(vertex + " ");

        Iterator<Integer> it = adjList[vertex].listIterator();
        while (it.hasNext()) {
            int next = it.next();
            if (!visited[next]) {
                DFSUtil(next, visited);
            }
        }
    }

    // BFS 算法
    void BFS(int startVertex) {
        boolean[] visited = new boolean[vertices];
        LinkedList<Integer> queue = new LinkedList<>();

        visited[startVertex] = true;
        queue.add(startVertex);

        while (queue.size() != 0) {
            int vertex = queue.poll();
            System.out.print(vertex + " ");

            Iterator<Integer> it = adjList[vertex].listIterator();
            while (it.hasNext()) {
                int next = it.next();
                if (!visited[next]) {
                    visited[next] = true;
                    queue.add(next);
                }
            }
        }
    }

    public static void main(String[] args) {
        Graph g = new Graph(6);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 2);
        g.addEdge(2, 0);
        g.addEdge(2, 3);
        g.addEdge(3, 3);
        g.addEdge(4,5);

        System.out.println("DFS starting from vertex 2:");
        g.DFS(2);  // Output: 2 0 1 3

        System.out.println("\nBFS starting from vertex 2:");
        g.BFS(2); // Output: 2 0 3 1
    }
}

DFS和BFS的区别与应用场景?

DFS使用栈(递归调用本质上也是栈)来记住下一步可能访问的顶点,因此它会尽可能深地搜索图的分支。适用于寻找路径、连通性检测等,尤其是在需要探索所有可能路径的情况下。例如,迷宫求解、拓扑排序等。但要注意,如果图包含环,DFS可能陷入无限循环,需要额外的机制来避免。

立即学习“Java免费学习笔记(深入)”;

如何用Java实现图的遍历 Java图的DFS和BFS算法示例

BFS使用队列来记住下一步可能访问的顶点,它会先访问所有邻近的顶点,然后再深入下一层。适用于寻找最短路径、网络爬虫等。例如,社交网络中查找两个人之间的最短连接路径。BFS保证找到的是最短路径,因为它是一层一层地搜索。

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载

如何优化Java图遍历的性能?

如何用Java实现图的遍历 Java图的DFS和BFS算法示例

性能优化主要集中在两个方面:减少不必要的访问和提高数据结构的效率。

  1. 使用合适的数据结构:邻接表通常比邻接矩阵更节省空间,尤其是在稀疏图中。在上面的代码示例中,我们使用了邻接表。
  2. 避免重复访问:visited 数组是关键。确保在访问顶点之前检查它是否已经被访问过。
  3. 并行化:对于大型图,可以考虑使用多线程来并行执行遍历。例如,可以将图分割成多个子图,然后并行地遍历这些子图。但需要注意线程安全问题。
  4. 减少内存占用:如果图非常大,可以考虑使用外部存储(例如,数据库)来存储图的结构。
  5. 迭代 vs. 递归 (DFS):在 Java 中,递归深度有限制。对于大型图,使用迭代版本的 DFS 可能更安全,因为它不会受到栈溢出的影响。

图的遍历在实际项目中的应用案例?

  1. 社交网络分析:查找用户之间的关系、推荐好友、检测社区结构。例如,可以使用 BFS 找到与某个用户有共同好友的用户。
  2. 网络爬虫:抓取网页、分析链接结构。网络爬虫通常使用 BFS 来遍历互联网上的网页。
  3. 路径查找:在地图应用中查找两个地点之间的最短路径。可以使用 Dijkstra 算法或 A* 算法,它们都基于图的遍历。
  4. 推荐系统:根据用户的历史行为,推荐相关的商品或内容。例如,可以使用图来表示用户和商品之间的关系,然后使用图的遍历算法来找到与用户兴趣相似的商品。
  5. 编译器:在编译器的语法分析阶段,可以使用图的遍历算法来构建抽象语法树。
  6. 垃圾回收:在垃圾回收算法中,可以使用图的遍历算法来标记所有可达的对象。

除了DFS和BFS,还有其他的图遍历算法吗?

虽然DFS和BFS是最常见的图遍历算法,但还有其他一些算法,它们在特定场景下可能更适用。

  1. Dijkstra 算法:用于查找带权图中两个顶点之间的最短路径。它是一种贪心算法,每次选择当前距离起点最近的顶点进行扩展。
  2. A* 算法:是 Dijkstra 算法的改进版本,它使用启发式函数来估计从当前顶点到目标顶点的距离,从而更快地找到最短路径。
  3. Floyd-Warshall 算法:用于查找图中所有顶点对之间的最短路径。它是一种动态规划算法,通过迭代的方式更新顶点之间的距离。
  4. 拓扑排序:用于有向无环图 (DAG) 的顶点排序,使得对于图中的每条有向边 (u, v),顶点 u 在排序中出现在顶点 v 之前。可以使用 DFS 或 BFS 来实现拓扑排序。
  5. 最小生成树算法 (Prim's 和 Kruskal's):虽然不是严格意义上的图遍历算法,但它们都涉及到对图的边的选择和遍历,用于找到连接所有顶点的最小权重的边集合。

选择哪种算法取决于具体的应用场景和需求。例如,如果需要查找最短路径,Dijkstra 算法或 A* 算法可能更合适。如果需要对有向无环图进行排序,拓扑排序算法是最佳选择。

热门AI工具

更多
PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2721

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

376

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

417

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

492

2026.05.09

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6427

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2688

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4538

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

1269

2025.12.24

Uvicorn使用教程
Uvicorn使用教程

本专题汇总了Uvicorn使用教程与启动运行指南,涵盖其作为Python ASGI服务器的定位与特点,以及命令行启动(uvicorn main:app --reload)、参数配置(host/port/workers)、程序内嵌运行与Gunicorn结合部署等核心用法。同时整理了热重载调试、日志配置与生产环境部署优化等技巧,助你快速掌握Uvicorn的运行与配置。

0

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn