迪杰斯特拉(Dijkstra)算法详解

【专栏】数据结构复习之路

这篇文章来自上述专栏中的一篇文章的节选:

【数据结构复习之路】图(严蔚敏版)两万余字&超详细讲解

想了解更多图论的知识,可以去看看本专栏 

Dijkstra 算法讲解:

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是:从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

这里我直接以书P189那个例子为基础进行讲解(附带书上的源代码)

先给出算法代码,然后结合着代码来讲可能会更容易理解:

/* 迪杰斯特拉(Dijkstra) 算法*/
void ShortestPath_Dijkstra(MGraph G, int v0, Patharc path, ShortPathTable dist)
{int v, w, k, min;int final[MaxVerterNum];		// final[w] = 1表示求得顶点 v0 至 vw的最短路径,即已访问过顶点vwfor (v = 0; v < G.vexNum; v++){final[v] = 0;				// 全部顶点初始化为未知最短路径状态dist[v] = G.Edge[v0][v];	// 将与v0点有连线的顶点加上权值path[v] = -1;				// 初始化路劲数组p为-1}dist[0] = 0;	// v0至v0路径为0final[0] = 1;	// v0至v0不需要路径/* 开始主循环,每次求得v0到某个顶点v的最短路径*/for (v = 1; v < G.vexNum; v++){min = INFINITY;		// 当前所知离v0顶点的最近距离for (w = 0; w < G.vexNum; w++)	// 寻找离v0最近的顶点{if (!final[w] && dist[w] < min){k = w;min = dist[w];	// w顶点离v0顶点更近}}final[k] = 1;	// 将目前找到的最近的顶点置为1for (w = 0; w < G.vexNum; w++)	// 修正当前最短路径及距离{/* 如果经过v顶点的路径比现在这条路径的长度短的话 */if (!final[w] && (min + G.Edge[k][w] < dist[w])){dist[w] = min + G.Edge[k][w];	// 修改当前路径长度path[w] = k;}}}
}

【1】初始化(执行上述代码前面一部分)

⚠️注意:这里的path[2] 、path[4]、path[5]没有初始化为0,主要是没必要,因为path[i] = -1,就表明 i 的前驱结点一定就是V0。

  • final[i]:标记各顶点是否已找到最短路径
  • dist[i]:最短路径长度
  • path[i]:路径上的前驱
    int v, w, k, min;int final[MaxVerterNum];  // final[w] = 1表示求得顶点 v0 至 vw的最短路径,即已访问过顶点vwfor (v = 0; v < G.vexNum; v++){final[v] = 0;		// 全部顶点初始化为未知最短路径状态dist[v] = G.Edge[v0][v]; // 将与v0点有连线的顶点加上权值path[v] = -1;		// 初始化路劲数组p为-1}dist[0] = 0;			// v0至v0路径为0final[0] = 1;			// v0至v0不需要路径

【2】找到距离V0最近的顶点,并修改当前路径长度 

/* 开始主循环,每次求得v0到某个顶点v的最短路径*/for (v = 1; v < G.vexNum; v++){min = INFINITY;		// 当前所知离v0顶点的最近距离for (w = 0; w < G.vexNum; w++)	// 寻找离v0最近的顶点{if (!final[w] && dist[w] < min){k = w;min = dist[w];	// w顶点离v0顶点更近}}final[k] = 1;			// 将目前找到的最近的顶点置为1for (w = 0; w < G.vexNum; w++)	// 修正当前最短路径及距离{/* 如果经过v顶点的路径比现在这条路径的长度短的话 */if (!final[w] && (min + G.Edge[k][w] < dist[w])){dist[w] = min + G.Edge[k][w];	// 修改当前路径长度path[w] = k;}}}

【3】 重复【2】 

​ 【4】重复【2】

【5】重复【2】


到这里,dist[i]里面存的就是从V0到 Vi 的最短路径长度,而通过path[i] 就能找到最短路径。

这里V1至始至终都没有更新的原因是:V0根本走不到V1。

看完上述图解,那么书上P190那个表格你肯定就明了:

下图的S相当于 final[i]依次被确定为1的次序

 这个表格建议大家要搞懂!可能有些学校会考察画图哦

⚠️注意:

迪杰斯特拉算法适用于求正权有向图中,源点到其余各个节点的最短路径。(图中可以有环,但不能有负权边)。

例如:如下图就不能使用迪杰斯特拉算法求节点 1 到其余各个节点的最短距离。

因为根据迪杰斯特拉算法,首先会更新dist[2] = 1 , final[2] = 1。由于final[2]被确定为1,即之后将不会再更新dist[2],而根据上图,显然结点1到结点2的最短路径为-1。


显然,Dijkstra 算法是基于贪心策略的。使用邻接矩阵或者带权的邻接表表示时,时间复杂度都是:O(|V|^{2})

这里的V是图里面的结点个数。
人们可能只希望找到从源点到某个特定顶点的最短路径,但这个问题和求解源点到其他所有顶点的最短路径一样复杂,时间复杂度也为O(|V|^{2})​ 


 我的个人博客,欢迎访问!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pip install skopt安装显示没有对应版本问题及解决

一、问题描述以及分析 &#xff08;一&#xff09;问题描述 ModuleNotFoundError: No module named skopt pip install skopt Note: you may need to restart the kernel to use updated packages.ERROR: Could not find a version that satisfies the requirement skopt (fro…

C语言编译器(C语言编程软件)完全攻略(第十三部分:VS2010使用教程(使用VS2010编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 十三、VS2010使用教程&#xff08;使用VS2010编写C语言程序&#xff09; 提示&#xff1a;VS2010 可以在 XP、Win7 和 Win8 下完美运行&#xff0c;但在 Win10 下可能会有兼容性问题&#xff0c;使用 Win10 的读者建议安装 VS2015 或…

JDBC练习查询所有内容

MySql表代码 -- 删除tb_brand表 drop table if exists tb_brand; -- 创建tb_brand表 create table tb_brand (-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段ordered int…

解决VNC连接Ubuntu服务器打开终端出现闪退情况

服务器环境 阿里云ECS服务器 操作系统&#xff1a;Ubuntu 20.0.4 如何使用VNC连接阿里云ECS服务器 1.阿里云官方指导&#xff1a;通过VNC搭建Ubuntu 18.04和20.04图形界面 2.新手入门ECS——ubuntu 20.04安装图形化界面和本地VNC连接 问题描述 使用VNC连接上新申请阿里云服…

C# 如何读取Excel文件

当处理Excel文件时&#xff0c;从中读取数据是一个常见的需求。通过读取Excel数据&#xff0c;可以获取电子表格中包含的信息&#xff0c;并在其他应用程序或编程环境中使用这些数据进行进一步的处理和分析。本文将分享一个使用免费库来实现C#中读取Excel数据的方法。具体如下&…

LLM之RAG实战(九)| 高级RAG 03:多文档RAG体系结构

在RAG&#xff08;检索和生成&#xff09;这样的框架内管理和处理多个文档有很大的挑战。关键不仅在于提取相关内容&#xff0c;还在于选择包含用户查询所寻求的信息的适当文档。基于用户查询对齐的多粒度特性&#xff0c;需要动态选择文档&#xff0c;本文将介绍结构化层次检索…

实现文件拖拽上传的功能

1 先来看一下效果 2 我们来看一下代码执行的结果&#xff1a; 我们创建目标的容器盒子 和可以展示数据的ul 监听进入目前盒子的事件 3 文件进入目标容器中解析文件

使用echarts制作柱状图并且下方带表格

实现效果: 调试地址: Examples - Apache ECharts 源码: option { title: { left: center, top: 0, text: 2022-05月 制造产量 达成情况(单位: 吨) (图1)\n\n集团目标产量: 106,675吨 集团实际产量: 2,636吨, textStyle:{ fontSize:20, colo…

3D Gaussian Splatting复现

最近3D Gaussian Splatting很火&#xff0c;网上有很多复现过程&#xff0c;大部分都是在Windows上的。Linux上配置环境会方便简单一点&#xff0c;这里记录一下我在Linux上复现的过程。 Windows下的环境配置和编译&#xff0c;建议看这个up主的视频配置&#xff0c;讲解的很细…

QT基础知识

QT基础知识 文章目录 QT基础知识1、QT是什么2、Qt的发展史3、为什么学习QT4、怎么学习QT1、工程的创建(环境的下载与安装请百度&#xff09;2、创建的工程结构说明3、怎么看帮助文档1、类使用的相关介绍2. 查看所用部件&#xff08;类&#xff09;的相应成员函数&#xff08;功…

【LeetCode】修炼之路-0001-Two Sum(两数之和)【python】【简单】

前言 计算机科学作为一门实践性极强的学科,代码能力的培养尤为重要。当前网络上有非常多优秀的前辈分享了LeetCode的最佳算法题解,这对于我们这些初学者来说提供了莫大的帮助,但对于我这种缺乏编程直觉的学习者而言,这往往难以消化吸收。&#xff08;为什么别人就能想出这么优雅…

牛刀小试 - C++实现贪吃蛇

参考文档 借鉴了这位大佬的博客及代码&#xff0c;键入代码后发现有很多报错&#xff0c;依次解决后成功运行 c 实现贪吃蛇&#xff08;含技术难点解析和完整代码&#xff09; 技术点&#xff1a; C中_kbhit()函数与_getch()函数 Windows API 坐标结构 COORD 句柄 HANDLE 获…

有能力,但是不赚钱,往往是因为没有这三个能力!2024最适合创业的细分行业,2024最适合创业的行业

很多人非常有能力&#xff0c;在学校是学霸&#xff0c;在公司是高管&#xff0c;但是出来自己创业就不行了。觉得是自己的能力不够&#xff0c;其实不是你的能力不够&#xff0c;而是你欠缺下面这三种能力。如果你能掌握这三种能力&#xff0c;就算之前是普通人尝试创业&#…

Hotspot源码解析-第十二章-线程栈保护页

了解保护页&#xff0c;先从几个问题开始吧 1、为什么线程栈有栈帧了&#xff0c;还要有保护页&#xff1f; 答&#xff1a;在操作系统中内存可以看成是一个大数组&#xff0c;这就有一个问题&#xff0c;线程之间可能会互相踩了别人的内存空间&#xff0c;所以栈空间也存在这…

UI自动化测试之Jenkins配置

背景&#xff1a; 团队下半年的目标之一是实现自动化测试&#xff0c;这里要吐槽一下&#xff0c;之前开发的测试平台了&#xff0c;最初的目的是用来做接口自动化测试和性能测试&#xff0c;但由于各种原因&#xff0c;接口自动化测试那部分功能整个废弃掉了&#xff0c;其中和…

word中MathType公式编号

直接上效果图&#xff1a; 步骤如下&#xff1a; 安装MathTypeword中安装MathType选项卡。设置MathType选项卡添加分隔符插入公式&#xff0c;自动生成右编码 接下来介绍每一步。 文章目录 1. 安装MathType2. Word中安装MathType选项卡3. 配置MathType选项4. 添加分隔符5. 插…

Halcon阈值处理的几种分割方法threshold/auto_threshold/binary_threshold/dyn_threshold

Halcon阈值处理的几种分割方法 文章目录 Halcon阈值处理的几种分割方法1. 全局阈值2. 基于直方图的自动阈值分割方法3. 自动全局阈值分割方法4. 局部阈值分割方法5. var_threshold算子6 . char_threshold 算子7. dual_threshold算子 在场景中选择物体或特征是图像测量或识别的重…

在宝塔Linux中安装Docker

前言 帮助使用宝塔的用户快速上手docke的安装 &#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Docker》。&#x1f3af;&#x1f3af…

图片上的水印怎么添加?简单易上手的3个方法

图片上的水印怎么添加&#xff1f;水印是一种透明的文字或图像叠加在原始图片上的技术。它能够涵盖版权信息、公司商标、作者名字或其他个人标识。很多人会通过添加水印的方法&#xff0c;来确保图片在分享或者是公开使用的时候&#xff0c;依然能够保留对自己原创内容的控制和…

【python入门】day19:学生管理系统需求分析、系统设计、主函数设计

需求分析 应具备功能—— 添加学生及成绩信息&#xff1b; 将学生信息保存到文件中&#xff1b; 修改和删除学生信息&#xff1b; 查询学生信息&#xff1b; 根据学生成绩进行排序&#xff1b; 统计学生的总分 系统设计 1.录入学生信息模块 2.查找 3.删除 4.修改 5.成绩排名…