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

news2025/1/21 1:01:53

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

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

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

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

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的最短路径,即已访问过顶点vw
	for (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路径为0
	final[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;	// 将目前找到的最近的顶点置为1
		for (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的最短路径,即已访问过顶点vw
	for (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路径为0
	final[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;			// 将目前找到的最近的顶点置为1
		for (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.coloradmin.cn/o/1344586.html

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

相关文章

如何理解李克特量表?选项距离相等+题目权重相等!

在学术研究中&#xff0c;通过开展问卷调查获取数据时&#xff0c;调查问卷分为量表题和非量表题。量表题就是测试受访者的态度或者看法的题目&#xff0c;大多采用李克特量表。 李克特量表是一种评分加总式态度量表&#xff08;attitude scale&#xff09;&#xff0c;由美国…

TCP/IP的五层网络模型

目录 封装&#xff08;打包快递&#xff09; 6.1应用层 6.2传输层 6.3网络层 6.4数据链路层 6.5物理层 分用&#xff08;拆快递&#xff09; 6.5物理层 6.4数据链路层 6.3网络层 6.2传输层 6.1应用层 封装&#xff08;打包快递&#xff09; 6.1应用层 此时做的数据…

【数字图像处理】比特平面分割,对比空间平滑滤波器的尺寸对滤波效果,对比均值滤波器和中值滤波器对图像的平滑效果

实验目的 对比均值滤波器和中值滤波器对图像的平滑效果&#xff1b;编程对比空间平滑滤波器的尺寸对滤波效果的影响&#xff1b;编程对比均值滤波器和中值滤波器对图像的平滑效果。 实验方法 比特平面分割 比特平面分层&#xff0c;代替突出灰度级范围&#xff0c;突出特定…

Unity坦克大战开发全流程——开始场景——设置界面

开始场景——设置界面 step1&#xff1a;设置面板的背景图 照着这个来设置就行了 step2&#xff1a;写代码 关联的按钮控件 监听事件函数 注意&#xff1a;要在start函数中再写一行HideMe函数&#xff0c;以便该面板能在一开始就能隐藏自己。 再在BeginPanel脚本中调用该函数即…

基于大语言模型LangChain框架:知识库问答系统实践

ChatGPT 所取得的巨大成功&#xff0c;使得越来越多的开发者希望利用 OpenAI 提供的 API 或私有化模型开发基于大语言模型的应用程序。然而&#xff0c;即使大语言模型的调用相对简单&#xff0c;仍需要完成大量的定制开发工作&#xff0c;包括 API 集成、交互逻辑、数据存储等…

为什么 export 导出一个字面量会报错而使用 export default 不会报错

核心 其实总的来说就是 export 导出的是变量的句柄&#xff08;或者说符号绑定、近似于 C 语言里面的指针&#xff0c;C里面的变量别名&#xff09;&#xff0c;而 export default 导出的是变量的值。 需要注意的是&#xff1a;模块里面的内容只能在模块内部修改&#xff0c;…

canvas绘制红绿灯路口

无图不欢&#xff0c;先上图 使用方法&#xff08;以vue3为例&#xff09; <template><canvas class"lane" ref"laneCanvas"></canvas> </template><script setup> import { ref, onMounted } from vue import Lane from …

IDEA中允许开启多个客户端

这个时候不要在客户端里创建socket对象时指定端口号了&#xff0c;否则会报错BindException

普通人如何月入过万?2024普通人创业适合干什么?

如果你的月收入不到1万块&#xff0c;也从来没有体验过一天就赚1万块是什么感觉的话&#xff0c;你还想创业&#xff1f;你如果想通过创业逆天改命&#xff0c;麻烦你一定要看完这篇文章。 普通人你要是想赚钱&#xff0c;一定要去赚那种能看得见的钱。 什么叫看得见的钱&…

35.搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…

服务器运行状况监控工具

服务器运行状况监视提供了每个服务器状态和性能的广泛概述&#xff0c;通过监控服务器指标&#xff0c;如 CPU 使用率、内存消耗、I/O、磁盘使用率、进程等&#xff0c;服务器运行状况监控可以避免服务器停机。 服务器性能监控指标 服务器是网络中最重要的组件之一&#xff0…

Android studio课程设计开发实现---日记APP

Android studio课程设计开发实现—日记APP 文章目录 Android studio课程设计开发实现---日记APP前言一、效果二、功能介绍1.主要功能2.涉及知识点 三、实现思路下载链接总结 前言 你们好&#xff0c;我是oy&#xff0c;介绍一个简易日记APP。 一、效果 1.启动页、引导页及登…

【北亚服务器数据恢复】san环境下LUN Mapping出错导致文件系统一致性出错的数据恢复案例

服务器数据恢复环境&#xff1a; san环境下的存储上一组由6块硬盘组建的RAID6&#xff0c;划分为若干LUN&#xff0c;MAP到跑不同业务的服务器上&#xff0c;服务器上层是SOLARIS操作系统UFS文件系统。 服务器故障&#xff1a; 业务需求需要增加一台服务器跑新增的应用&#xf…

社区医院挂号预约服务管理系统95an6

社区医院管理服务系统具有社区医院信息管理功能的选择。社区医院管理服务系统采用p[ython技术&#xff0c;基于django框架&#xff0c;mysql数据库进行开发&#xff0c;实现了首页、个人中心、用户管理、医生管理、预约医生管理、就诊信息管理、诊疗方案管理、病历信息管理、健…

人工智能工程师的前景怎么样

人工智能是未来的发展趋势&#xff0c;因此&#xff0c;人工智能工程师也将成为就业爆款。人工智能工程师负责创建和开发自动化系统、算法和机器学习模型&#xff0c;以实现自主决策和任务执行。由于人工智能在可穿戴设备、家庭自动化、智能城市和自动驾驶等领域都有广泛应用&a…

北斗卫星助力物流企业,打造智慧运输新时代

北斗卫星助力物流企业&#xff0c;打造智慧运输新时代 北斗卫星系统作为我国自主研发的卫星导航系统&#xff0c;近年来在智慧物流领域发挥了重要作用。通过北斗卫星系统的应用&#xff0c;物流企业可以实现智能化管理&#xff0c;提高运输效率&#xff0c;降低物流成本。越来…

前端三件套html/css/js的基本认识以及示例程序

简介 本文简要讲解了html,css,js.主要是让大家简要了解网络知识 因为实际开发中很少直接写html&css,所以不必过多纠结,了解一下架构就好 希望深度学习可以参考MDN和w3school HTML 基础 HTML (Hyper Text Markup Language) 不是一门编程语言,而是一种用来告知浏览器如…

微服务(1)

目录 1.什么是微服务&#xff1f;谈谈你对微服务的理解&#xff1f; 2.什么是Spring Cloud&#xff1f; 3.Springcloud中的组件有哪些&#xff1f; 3.具体说说SpringCloud主要项目&#xff1f; 5.SpringCloud项目部署架构&#xff1f; 1.什么是微服务&#xff1f;谈谈你对微…

OpenCV-Python(30):Harris角点检测

目标 理解Harris角点检测的概念掌握函数cv2.cornerHarris()、cv2.cornerSubPix()的用法 Harris算法原理 通过前面的图像特征介绍&#xff0c;我们知知道了角点的一个特性&#xff1a;向任何方向移动变化都很大。Chris_Harris 和Mike_Stephens 在1988 年的文章《A Combined Co…

【滑动窗口】C++算法:K 个不同整数的子数组

作者推荐 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 本题涉及知识点 滑动窗口 LeetCoe992 K 个不同整数的子数组 给定一个正整数数组 nums和一个整数 k&#xff0c;返回 nums 中 「好子数组」 的数目。 如果 nums 的某个子数组中不同整数的个数恰好为 …