最短路径算法:Dijkstra算法

引言

在图论中,最短路径算法用于找到从一个顶点到另一个顶点的最短路径。Dijkstra算法是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出的一种用于计算加权图中单源最短路径的经典算法。本文将详细介绍Dijkstra算法的定义、步骤及其实现。

Dijkstra算法

定义

Dijkstra算法是一种贪心算法,用于计算一个顶点到图中所有其他顶点的最短路径。该算法假设图中不存在负权重的边。

算法步骤

  1. 初始化:设定源顶点的距离为0,其余顶点的距离为正无穷大。将所有顶点标记为未访问。
  2. 从未访问的顶点中选择距离源顶点最小的顶点作为当前顶点。
  3. 对于当前顶点的每个邻接顶点,计算从源顶点经过当前顶点到达该邻接顶点的距离。如果该距离小于已知的距离,则更新已知距离。
  4. 将当前顶点标记为已访问。
  5. 重复步骤2至4,直到所有顶点都被访问。

示例

假设我们有一个带权无向图,顶点集合为 ({A, B, C, D, E}),边和权重集合为 ({(A, B, 2), (A, C, 4), (B, C, 1), (B, D, 7), (C, E, 3), (D, E, 1)})。
2 4 1 7 3 1 A B C D E

Dijkstra算法实现

下面是用Java实现Dijkstra算法的代码示例:

java 复制代码
import java.util.*;

public class DijkstraAlgorithm {
    private int vertices; // 顶点数量
    private int[][] graph; // 图的邻接矩阵

    public DijkstraAlgorithm(int vertices) {
        this.vertices = vertices;
        graph = new int[vertices][vertices];
    }

    // 添加边
    public void addEdge(int src, int dest, int weight) {
        graph[src][dest] = weight;
        graph[dest][src] = weight; // 无向图
    }

    // 计算从源顶点到所有顶点的最短路径
    public void dijkstra(int src) {
        int[] dist = new int[vertices]; // 最短距离数组
        boolean[] visited = new boolean[vertices]; // 已访问顶点标记数组

        // 初始化距离数组,所有顶点的距离设为正无穷大
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[src] = 0;

        for (int i = 0; i < vertices - 1; i++) {
            // 从未访问顶点中选择距离源顶点最近的顶点
            int u = minDistance(dist, visited);
            visited[u] = true;

            // 更新u的邻接顶点的距离
            for (int v = 0; v < vertices; v++) {
                if (!visited[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) {
                    dist[v] = dist[u] + graph[u][v];
                }
            }
        }

        printSolution(dist);
    }

    // 查找未访问顶点中距离源顶点最近的顶点
    private int minDistance(int[] dist, boolean[] visited) {
        int min = Integer.MAX_VALUE, minIndex = -1;

        for (int v = 0; v < vertices; v++) {
            if (!visited[v] && dist[v] <= min) {
                min = dist[v];
                minIndex = v;
            }
        }

        return minIndex;
    }

    // 打印最短路径
    private void printSolution(int[] dist) {
        System.out.println("顶点\t 距离源顶点");
        for (int i = 0; i < vertices; i++) {
            System.out.println(i + "\t\t" + dist[i]);
        }
    }

    public static void main(String[] args) {
        int vertices = 5;
        DijkstraAlgorithm graph = new DijkstraAlgorithm(vertices);
        graph.addEdge(0, 1, 2);
        graph.addEdge(0, 2, 4);
        graph.addEdge(1, 2, 1);
        graph.addEdge(1, 3, 7);
        graph.addEdge(2, 4, 3);
        graph.addEdge(3, 4, 1);

        graph.dijkstra(0); // 从顶点0开始计算最短路径
    }
}

Dijkstra算法步骤图解

以下是对上述示例中Dijkstra算法步骤的图解:

  1. 初始化顶点距离和访问状态:
plaintext 复制代码
A: 0
B: ∞
C: ∞
D: ∞
E: ∞
  1. 选择距离最小的顶点A,并更新其邻接顶点B和C的距离:
plaintext 复制代码
A: 0
B: 2
C: 4
D: ∞
E: ∞
  1. 选择距离最小的顶点B,并更新其邻接顶点C和D的距离:
plaintext 复制代码
A: 0
B: 2
C: 3
D: 9
E: ∞
  1. 选择距离最小的顶点C,并更新其邻接顶点E的距离:
plaintext 复制代码
A: 0
B: 2
C: 3
D: 9
E: 6
  1. 选择距离最小的顶点E,并更新其邻接顶点D的距离:
plaintext 复制代码
A: 0
B: 2
C: 3
D: 7
E: 6
  1. 选择距离最小的顶点D,算法结束。

结论

通过上述讲解和实例代码,我们详细展示了Dijkstra算法的定义、步骤及其实现。Dijkstra算法是一种重要的最短路径算法,广泛应用于各种网络和图的场景。希望这篇博客对您有所帮助!


如果您觉得这篇文章对您有帮助,请关注我的CSDN博客,点赞并收藏这篇文章,您的支持是我持续创作的动力!


关键内容总结

  • Dijkstra算法的定义
  • Dijkstra算法的步骤
  • Dijkstra算法的实现及其图解

推荐阅读:深入探索设计模式专栏 ,详细讲解各种设计模式的应用和优化。点击查看:深入探索设计模式


特别推荐:设计模式实战专栏 ,深入解析设计模式的实际应用,提升您的编程技巧。点击查看:设计模式实战

如有任何疑问或建议,欢迎在评论区留言讨论。谢谢阅读!


测试代码的运行结果:

plaintext 复制代码
顶点	 距离源顶点
0		 0
1		 2
2		 3
3		 7
4		 6
相关推荐
喵叔哟3 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生9 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
hopetomorrow23 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
不是二师兄的八戒33 分钟前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php
小牛itbull33 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i42 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
闲暇部落44 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
爱编程的小生1 小时前
Easyexcel(2-文件读取)
java·excel
GIS瞧葩菜1 小时前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming19871 小时前
STL关联式容器之set
开发语言·c++