数据结构-最短路径算法实践

本文介绍了如何在Java中使用Dijkstra算法求解图中无负权边的最短路径问题,包括算法原理、Java代码实现及其在`Graph`类中的应用。同时提到了Dijkstra算法不适用于含有负权边的情况,可考虑使用Bellman-Ford算法。
摘要由CSDN通过智能技术生成

求解图中最短路径问题有多种算法,主要依赖于图的性质以及特定的需求。两种著名的算法是 Dijkstra 算法和 Bellman-Ford 算法。Dijkstra 算法适用于没有负权边的图,而 Bellman-Ford 算法可以处理带有负权边的图。

下面我将提供使用 Dijkstra 算法在 Java 中寻找最短路径的示例实现。Dijkstra 算法使用贪心策略,通过逐步更新节点到起点的距离,最终找到最短路径。

Dijkstra 算法 Java 实现:

import java.util.*;

class Graph {
    private int vertices; // 顶点的数量
    private List<List<Node>> adj; // 邻接表表示图

    public Graph(int vertices) {
        this.vertices = vertices;
        adj = new ArrayList<>();
        for (int i = 0; i < vertices; i++) {
            adj.add(new ArrayList<>());
        }
    }

    public void addEdge(int src, int dest, int weight) {
        adj.get(src).add(new Node(dest, weight));
    }

    public void dijkstra(int src) {
        int dist[] = new int[vertices]; // 存储到各顶点的最短距离
        boolean finalized[] = new boolean[vertices]; // 标记顶点最短路径是否确定
        Arrays.fill(dist, Integer.MAX_VALUE); // 初始化距离为无穷大
        dist[src] = 0; // 源点到自身的距离为 0

        for (int count = 0; count < vertices - 1; count++) {
            int u = findMinDistance(dist, finalized); // 选择最小距离的未确定顶点
            finalized[u] = true; // 确定该顶点的最短路径
            for (Node node : adj.get(u)) {
                if (!finalized[node.dest] && dist[u] + node.weight < dist[node.dest]) {
                    dist[node.dest] = dist[u] + node.weight;
                }
            }
        }
        printSolution(dist); // 打印最短距离
    }

    private int findMinDistance(int dist[], boolean finalized[]) {
        int min = Integer.MAX_VALUE, index = -1;
        for (int i = 0; i < vertices; i++) {
            if (!finalized[i] && dist[i] <= min) {
                min = dist[i];
                index = i;
            }
        }
        return index;
    }

    private void printSolution(int dist[]) {
        System.out.println("顶点到目标顶点的最短距离");
        for (int i = 0; i < vertices; i++) {
            System.out.println(i + " - " + dist[i]);
        }
    }

    class Node {
        int dest;
        int weight;

        public Node(int dest, int weight) {
            this.dest = dest;
            this.weight = weight;
        }
    }
}

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

        graph.dijkstra(0); // 以顶点 0 为源点计算最短路径
    }
}

在上面的代码中,我们定义了一个图类 Graph,图中的每个节点 Node 包含目标节点 dest 和边的权重 weight。图中的 addEdge 方法用于添加有向边。Dijkstra 算法是通过 dijkstra 方法实现的,它计算并打印从源点到其他所有节点的最短路径。

findMinDistance 方法被用于寻找当前最短路径还未确定的节点中,距离源点最近的节点。然后,我们更新其邻接节点的最短距离。这个过程重复直到所有节点的最短路径都被确定。

请注意,Dijkstra 算法不能处理包含负权边的图,因为这会导致算法产生不正确的结果。如果你的图包含负权边,可以考虑使用 Bellman-Ford 算法。

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值