深入理解 Dijkstra 算法:原理、实现与优化

news2025/5/15 15:16:37

算法核心思想

Dijkstra算法采用贪心策略,其核心思想可以概括为:

  1. 初始化:设置起点到自身的距离为0,到其他所有点的距离为无穷大

  2. 迭代处理

    • 从未处理的顶点中选择当前距离起点最近的顶点

    • 标记该顶点为已处理

    • 通过该顶点更新其邻居顶点的距离

  3. 终止条件:所有顶点都被处理过

算法实现详解

数据结构准备

我们使用以下数据结构:

2. 主循环(进行 n-1 次,每次确定一个节点的最短路径)

初始状态:


第一次循环(i=1):


第二次循环(i=2):


第三次循环(i=3):

3. 最终结果


代码问题修正

你的代码有一个小问题:

cpp

复制

下载

int t = -1;  // 初始化为 -1
for (int j = 1; j <= n; j++)
    if (!st[j] && (t == -1 || d[j] < d[t]))
        t = j;
if (t == -1) break;  // 所有节点已处理或不可达

图解流程

初始 d: [0, INF, INF]
第一次循环(t=1):
   - 更新 d[2]=2, d[3]=4 → d: [0, 2, 4]
第二次循环(t=2):
   - 更新 d[3]=3 → d: [0, 2, 3]
最终结果:d[3] = 3

  • g[N][N]:邻接矩阵存储图的边权

  • d[N]:存储从起点到各顶点的最短距离

  • st[N]:标记顶点是否已被处理

  • 我们以下面的图为例:

    3 3       // 3个节点,3条边
    1 2 2     // 边 1→2,权重=2
    2 3 1     // 边 2→3,权重=1
    1 3 4     // 边 1→3,权重=4
    1. 初始化
  • g[N][N](邻接矩阵)初始化为 0x3f3f3f3fINF)。

  • 输入边后,g 变为:

    g[1][2] = 2
    g[2][3] = 1
    g[1][3] = 4
    其余 g[i][j] = INF
  • d[N](最短距离数组)初始化为 INF,然后 d[1] = 0(起点到自身距离为0)。

  • st[N](标记数组)初始化为 0(未处理)。

  • d = [0, INF, INF]

  • st = [0, 0, 0]

  • 找未处理的最近节点 t

    • j=1d[1]=0st[1]=0 → t=1

    • j=2d[2]=INF > d[1],不更新 t

    • j=3d[3]=INF > d[1],不更新 t

    • 最终 t=1(节点1)。

  • 标记 st[1] = 1(已处理)。

  • 用节点1更新邻居:

    • j=2d[1] + g[1][2] = 0 + 2 < INF → d[2] = 2

    • j=3d[1] + g[1][3] = 0 + 4 < INF → d[3] = 4

    • 更新后 d = [0, 2, 4]

  • 找未处理的最近节点 t

    • j=1st[1]=1(已处理,跳过)

    • j=2d[2]=2st[2]=0 → t=2

    • j=3d[3]=4 > d[2],不更新 t

    • 最终 t=2(节点2)。

  • 标记 st[2] = 1(已处理)。

  • 用节点2更新邻居:

    • j=3d[2] + g[2][3] = 2 + 1 = 3 < 4 → d[3] = 3

    • 更新后 d = [0, 2, 3]

  • 虽然循环条件是 i < n(即 i=1, 2),但你的代码中 i 从 1 到 n-1(共 n-1=2 次),所以不会执行第三次循环。

  • d = [0, 2, 3],所以 d[n] = d[3] = 3

  • 输出 3(即 1→2→3 的路径,权重 2+1=3,比直接 1→3 的 4 更短)。

  • t 的初始值应为 -1 而不是 0,因为节点编号从 1 开始,t=0 可能导致逻辑错误(如果所有 d[j]=INFt 会保持 0,而 g[t][j] 会访问 g[0][j],越界)。
    修正:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376183.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件设计师-下午题-试题4(15分)

目录 1 回溯法 1.1 N皇后问题 1.1.1 非递归求解N皇后问题 1.1.2 递归求解N皇后问题 1.2 真题 2 分治法 2.1 真题 3 动态规划法 3.1 0-1背包问题 3.2 真题 1 回溯法 1.1 N皇后问题 上图Q4与Q2在同一列且与Q1在同一斜线&#xff0c;先回溯到上一个皇后改变Q3皇后的位置…

leetcode二叉树相关题目复习(C语言版)

目录 1.单值二叉树 2.相同的树 3.对称二叉树 4.二叉树的前序遍历 5.另一颗树的子树 1.单值二叉树 思路1&#xff1a; 判断根节点、左节点与右节点的值是否相等&#xff0c;因为正向判断&#xff08;即判断三值相等返回true&#xff09;比较麻烦&#xff08;不能根节点满足…

第十九次博客打卡

今天学习的内容是Java中的常见循环。 在 Java 中&#xff0c;常见的循环结构主要有以下几种&#xff1a;for 循环、while 循环、do-while 循环以及增强型 for 循环&#xff08;也称为 for-each 循环&#xff09;。 1. for 循环 for 循环是一种非常灵活的循环结构&#xff0c…

浅聊一下数据库的索引优化

背景 这里的索引说的是关系数据库&#xff08;MSSQL&#xff09;中的索引。 本篇不是纯技术性的内容&#xff0c;只是聊一次性能调优的经历&#xff0c;包含到一些粗浅的实现和验证手段&#xff0c;所以&#xff0c;大神忽略即可。 额…对了&#xff0c;笔者对数据库的优化手段…

山东大学软件学院软件工程计算机图形学复习笔记(2025)

写在前面&#xff1a; 现在是考完试的第二天&#xff0c;考试的内容还是有一部分没有复习到的…… 根据三角形的3个顶点坐标和内部某点坐标D&#xff0c;写出点D的基于面积的权重坐标Bresenham的算法描述与改进策略&#xff08;这里ppt上很不清晰&#xff09;以及直线反走样的…

【Docker】Docker Compose方式搭建分布式内存数据库(Redis)集群

文章目录 开发环境开发流程运行效果Docker Desktop桌面中的Redis结点启动图Redis结点1的打印日志情况图 配置代码命令行启动配置文件: README.md删除集群信息新建数据目录本地Redis的结点的域名,并添加到/etc/hosts文件的末尾域名映射启动集群结点创建集群关闭集群结点 redis-c…

如何在 Bash 中使用 =~ 操作符 ?

在 Bash 脚本世界中&#xff0c;有各种操作符可供我们使用&#xff0c;使我们能够操作、比较和测试数据。其中一个操作符是 ~ 操作符。这个操作符经常被忽视&#xff0c;但功能非常强大&#xff0c;它为我们提供了一种使用正则表达式匹配字符串模式的方法。 ~ 操作符语法 语法…

科学养生指南:打造健康生活

在快节奏的现代生活中&#xff0c;健康养生成为人们关注的焦点。科学养生无需复杂理论&#xff0c;掌握以下几个关键要素&#xff0c;就能为身体构筑坚实的健康防线。​ 合理饮食是健康的基础。世界卫生组织建议&#xff0c;每天应摄入至少 5 份蔬菜和水果&#xff0c;保证维生…

华为OD机试真题——单词接龙(首字母接龙)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

计算机网络-MPLS VPN基础概念

前面几篇文章我们学习了MPLS的标签转发原理&#xff0c;有静态标签分发和LDP动态标签协议&#xff0c;可以实现LSR设备基于标签实现数据高效转发。现在开始学习MPLS在企业实际应用的场景-MPLS VPN。 一、MPLS VPN概念 MPLS&#xff08;多协议标签交换&#xff09;位于TCP/IP协…

【Linux系列】bash_profile 与 zshrc 的编辑与加载

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Spring Boot中的拦截器!

每次用户请求到达Spring Boot服务端&#xff0c;你是否需要重复写日志、权限检查或请求格式化代码&#xff1f;这些繁琐的“前置后置”工作让人头疼&#xff01;好在&#xff0c;Spring Boot拦截器如同一道智能关卡&#xff0c;统一处理请求的横切逻辑&#xff0c;让代码优雅又…

基于 Spring Boot 瑞吉外卖系统开发(十五)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;十五&#xff09; 前台用户登录 在登录页面输入验证码&#xff0c;单击“登录”按钮&#xff0c;页面会携带输入的手机号和验证码向“/user/login”发起请求。 定义UserMapper接口 Mapper public interface UserMapper exte…

计算机网络笔记(二十三)——4.5IPv6

4.5.1IPv6的基本首部 IPv6 的基本首部相对于 IPv4 进行了重大简化和优化&#xff0c;固定长度为 40 字节&#xff0c;大幅提升了路由器的处理效率。以下是各字段的详细说明&#xff1a; IPv6 基本首部字段组成 字段名位数作用描述版本 (Version)4 bits固定值为 6&#xff0c…

推荐一个Winform开源的UI工具包

从零学习构建一个完整的系统 推荐一个开源、免费的适合.NET WinForms 控件的套件。 项目简介 Krypton是一套开源的.Net组件&#xff0c;用于快速构建具有丰富UI交互的WinForms应用程序。 丰富的UI控件&#xff0c;提供了48个基础控件&#xff0c;如按钮、文本框、标签、下拉…

位与运算

只有当除数是 2 的幂次方&#xff08;如 2、4、8、16...&#xff09;时&#xff0c;取模运算才可以转换为位运算。 int b 19;int a1 b % 16; // 传统取模运算int a2 b & 15; // 位运算替代取模printf("b %d\n", b);printf("b %% 8 %d\n",…

趣味编程:四叶草

概述&#xff1a;在万千三叶草中寻觅&#xff0c;只为那一抹独特的四叶草之绿&#xff0c;它象征着幸运与希望。本篇博客主要介绍四叶草的绘制。 1. 效果展示 绘制四叶草的过程是一个动态的过程&#xff0c;因此博客中所展示的为绘制完成的四叶草。 2. 源码展示 #define _CR…

城市生命线综合管控系统解决方案-守护城市生命线安全

一、政策背景 国务院办公厅《城市安全风险综合监测预警平台建设指南》‌要求&#xff1a;将燃气、供水、排水、桥梁、热力、综合管廊等纳入城市生命线监测体系&#xff0c;建立"能监测、会预警、快处置"的智慧化防控机制。住建部‌《"十四五"全国城市基础…

# 2-STM32F103-复位和时钟控制RCC

STM32-复位和时钟控制RCC 2-STM32-复位和时钟控制RCC摘要说明本文参考资料如下&#xff1a; 一、STM32最小系统回顾STM32F103C8T6核心板原理图 二、复位三、时钟3.1 时钟树3.2 STM32启动过程3.2 SystemInit()函数3.2.1 SystemInit()第1句&#xff1a;3.2.2 SystemInit()第2句&a…

多模态大语言模型arxiv论文略读(七十五)

PosterLLaVa: Constructing a Unified Multi-modal Layout Generator with LLM ➡️ 论文标题&#xff1a;PosterLLaVa: Constructing a Unified Multi-modal Layout Generator with LLM ➡️ 论文作者&#xff1a;Tao Yang, Yingmin Luo, Zhongang Qi, Yang Wu, Ying Shan, C…