Java 无向图两点最短路径的实现

在图论中,无向图是一种常见的模型,它由顶点(点)和边(连接顶点的线)组成。当我们需要在一个无向图中寻找两点之间的最短路径时,可以借助一些图算法,如Dijkstra算法。此外,对于小规模的无向图,广度优先搜索(BFS)也能有效地求解这个问题。

理论基础

无向图

无向图的特点是边没有方向,即从顶点A到顶点B的路径与从B到A是等价的。此外,边的权重可以是相同的(如每条边权重为1),也可以不同(如不同的地理距离或电信距离)。

Dijkstra算法

Dijkstra算法是一种贪心算法,能够在带权图中寻找单源最短路径,适用于所有边权为非负数的图。

Java实现

我们以Java为例实现一个求无向图两点间最短路径的简单程序。

代码示例

import java.util.*;

class Graph {
    private final Map<Integer, List<Edge>> adjacencyList = new HashMap<>();

    private static class Edge {
        int target;
        int weight;

        Edge(int target, int weight) {
            this.target = target;
            this.weight = weight;
        }
    }

    public void addEdge(int source, int target, int weight) {
        adjacencyList.putIfAbsent(source, new ArrayList<>());
        adjacencyList.putIfAbsent(target, new ArrayList<>());
        adjacencyList.get(source).add(new Edge(target, weight));
        adjacencyList.get(target).add(new Edge(source, weight)); // 无向
    }

    public int dijkstra(int start, int end) {
        Map<Integer, Integer> distances = new HashMap<>();
        PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(edge -> edge.weight));

        for (int vertex : adjacencyList.keySet()) {
            distances.put(vertex, Integer.MAX_VALUE);
        }
        distances.put(start, 0);
        priorityQueue.add(new Edge(start, 0));

        while (!priorityQueue.isEmpty()) {
            Edge current = priorityQueue.poll();
            if (current.target == end) {
                return distances.get(current.target);
            }

            for (Edge edge : adjacencyList.get(current.target)) {
                int newDist = distances.get(current.target) + edge.weight;

                if (newDist < distances.get(edge.target)) {
                    distances.put(edge.target, newDist);
                    priorityQueue.add(new Edge(edge.target, newDist));
                }
            }
        }
        return -1; // 如果无法到达
    }
}

使用示例

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

        int shortestPath = graph.dijkstra(0, 4);
        System.out.println("最短路径为: " + shortestPath); // 输出最短路径
    }
}

在上面的代码中,我们定义了一个Graph类,该类包含了一个邻接表adjacencyList来表示图的结构。addEdge方法可以添加边,dijkstra方法则可以计算从起点到终点的最短路径。

流程图

下面是采用Mermaid语法描述的执行流程图:

flowchart TD
    A[开始] --> B[初始化图]
    B --> C[添加边]
    C --> D{是否到达终点}
    D -- 是 --> E[返回最短路径]
    D -- 否 --> F[遍历相邻节点]
    F --> D
    E --> G[结束]

饼状图

在实际应用中,我们可能需要展示最短路径的分布情况。下面是一个示例饼状图,代表不同路径权重的占比。

pie
    title 路径权重分布
    "权重1": 30
    "权重2": 25
    "权重3": 20
    "权重4": 15
    "权重5": 10

结尾

通过上述示例和解释,我们不仅了解了无向图的基本概念和Dijkstra算法的实现细节,还知道如何在Java中通过简单的代码实现这一功能。图论不仅在计算机科学中有着广泛的应用,还能解决现实世界中的诸多问题,如最优路线规划、网络分析等。在未来的实际应用中,无向图和对应的算法将继续发挥巨大的作用。希望这篇文章能帮助你更深入地理解无向图最短路径的问题!