You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中为String类型顶点的SimpleWeightedGraph实现BFS与DFS

为JGraphT的SimpleWeightedGraph实现BFS与DFS遍历

需求说明

需要使用Java语言,为顶点类型为String的SimpleWeightedGraph实现广度优先搜索(Breadth First Search,简称BFS)与深度优先搜索(Depth First Search,简称DFS)遍历功能。

现有已完成功能

当前已编写的代码已经完成以下功能,且均验证可正常运行:

  • 声明SimpleWeightedGraph实例
  • 创建图的各个顶点
  • 将顶点添加到图结构中
  • 创建DefaultWeightedEdge默认加权边,添加边并设置对应权重
  • 获取并打印顶点"a"到顶点"e"的最短路径
  • 获取并打印顶点"a"到顶点"e"的路径总权重
  • 获取并打印顶点"a"到顶点"e"路径的起始顶点
  • 获取并打印顶点"a"到顶点"e"路径的终止顶点
    当前构建的无向加权图结构如下:
(A)---68--(B)
     | \    / |
     | 9\  /74|
   10|   (C)  |24
     | 8/  \55|
     | /    \ |
    (D)---7--(E)

现有完整代码

import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;

public class GrapgsExample {

    public static void main(String[] args) {


        // below is my graph...
        //
        //     (A)---68--(B)
        //      | \    / |
        //      | 9\  /74|
        //    10|   (C)  |24
        //      | 8/  \55|
        //      | /    \ |
        //     (D)---7--(E)
        //

        //declare SimpleWeightedGraph
        SimpleWeightedGraph<String, DefaultWeightedEdge> graph;
        graph = new SimpleWeightedGraph<>(DefaultWeightedEdge.class);

        // create vertices

        String a = "a";
        String b = "b";
        String c = "c";
        String d = "d";
        String e = "e";

        // add the vertices in graph

        graph.addVertex(a);
        graph.addVertex(b);
        graph.addVertex(c);
        graph.addVertex(d);
        graph.addVertex(e);

        // create default weighted edges and add edges and set edgeWeights.
        DefaultWeightedEdge aToB = graph.addEdge(a, b);
        graph.setEdgeWeight(aToB, 68);

        DefaultWeightedEdge aT0c = graph.addEdge(a,c);
        graph.setEdgeWeight(aT0c, 9);

        DefaultWeightedEdge aT0d = graph.addEdge(a,d);
        graph.setEdgeWeight(aT0d, 10);

        DefaultWeightedEdge bT0c = graph.addEdge(b,c);
        graph.setEdgeWeight(bT0c, 74);

        DefaultWeightedEdge bT0e = graph.addEdge(b,e);
        graph.setEdgeWeight(bT0e, 24);

        DefaultWeightedEdge cT0e = graph.addEdge(c,e);
        graph.setEdgeWeight(cT0e, 55);

        DefaultWeightedEdge cT0d = graph.addEdge(c,d);
        graph.setEdgeWeight(cT0d, 8);

        DefaultWeightedEdge dT0e = graph.addEdge(d,e);
        graph.setEdgeWeight(dT0e, 7);

        // shortest path
        DijkstraShortestPath<String, DefaultWeightedEdge> path = new DijkstraShortestPath<>(graph);

        var shortestPath = path.getPath(a, e);
        var weight = path.getPath(a, e).getWeight();
        var startVertex = path.getPath(a, e).getStartVertex();
        var endVertex = path.getPath(a, e).getEndVertex();


        System.out.println("shortest path from \"a\" to \"e\" "+ shortestPath); //this get the shortest path which is [(a : d), (d : e)]
        System.out.println("weight from a to e "+weight); // the weight is 10 + 7 = 17
        System.out.println("start Vertex between \"a\" and \"e\" is "+startVertex);
        System.out.println("end Vertex between \"a\" and \"e\" is "+endVertex);


        // Breadth First Search and Depth First Search... not implemented

    }
}

实现方案

方法1:调用JGraphT内置遍历器(生产环境推荐)

JGraphT自带封装完善的遍历工具类,无需手动编写队列、栈逻辑,稳定性更高。首先导入两个遍历类:

import org.jgrapht.traverse.BreadthFirstIterator;
import org.jgrapht.traverse.DepthFirstIterator;

在原代码标注的BFS/DFS待实现位置添加以下代码:

// BFS遍历,起点为顶点a
System.out.println("=== BFS遍历结果(从a出发) ===");
BreadthFirstIterator<String, DefaultWeightedEdge> bfsIterator = new BreadthFirstIterator<>(graph, a);
while (bfsIterator.hasNext()) {
    System.out.print(bfsIterator.next() + " ");
}
System.out.println();

// DFS遍历,起点为顶点a
System.out.println("=== DFS遍历结果(从a出发) ===");
DepthFirstIterator<String, DefaultWeightedEdge> dfsIterator = new DepthFirstIterator<>(graph, a);
while (dfsIterator.hasNext()) {
    System.out.print(dfsIterator.next() + " ");
}

运行输出参考(邻接点遍历顺序由边存储顺序决定,符合遍历规则即为正确结果):

=== BFS遍历结果(从a出发) ===
a b c d e 
=== DFS遍历结果(从a出发) ===
a d e c b 

方法2:手动实现遍历(用于原理理解)

如果需要自己实现遍历逻辑,可以参考以下代码,不依赖JGraphT额外的遍历包:

import java.util.*;

// 手动实现BFS
public static List<String> bfs(SimpleWeightedGraph<String, DefaultWeightedEdge> graph, String start) {
    List<String> res = new ArrayList<>();
    Set<String> visited = new HashSet<>();
    Queue<String> queue = new LinkedList<>();
    queue.offer(start);
    visited.add(start);
    while (!queue.isEmpty()) {
        String cur = queue.poll();
        res.add(cur);
        for (DefaultWeightedEdge edge : graph.edgesOf(cur)) {
            String neighbor = graph.getEdgeTarget(edge).equals(cur) ? graph.getEdgeSource(edge) : graph.getEdgeTarget(edge);
            if (!visited.contains(neighbor)) {
                visited.add(neighbor);
                queue.offer(neighbor);
            }
        }
    }
    return res;
}

// 手动实现DFS
public static List<String> dfs(SimpleWeightedGraph<String, DefaultWeightedEdge> graph, String start) {
    List<String> res = new ArrayList<>();
    Set<String> visited = new HashSet<>();
    Deque<String> stack = new ArrayDeque<>();
    stack.push(start);
    while (!stack.isEmpty()) {
        String cur = stack.pop();
        if (visited.contains(cur)) continue;
        visited.add(cur);
        res.add(cur);
        for (DefaultWeightedEdge edge : graph.edgesOf(cur)) {
            String neighbor = graph.getEdgeTarget(edge).equals(cur) ? graph.getEdgeSource(edge) : graph.getEdgeTarget(edge);
            if (!visited.contains(neighbor)) {
                stack.push(neighbor);
            }
        }
    }
    return res;
}

调用方式:

System.out.println("手动实现BFS结果:" + bfs(graph, a));
System.out.println("手动实现DFS结果:" + dfs(graph, a));

内容的提问来源于stack exchange,提问作者Tinyiko Chauke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 08:09:42