迪杰斯特拉(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.hqwc.cn/news/310421.html

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

相关文章

数据库开发之子查询案例的详细解析

1.5 案例 基于之前设计的多表案例的表结构&#xff0c;我们来完成今天的多表查询案例需求。 准备环境 将资料中准备好的多表查询的数据准备的SQL脚本导入数据库中。 分类表&#xff1a;category 菜品表&#xff1a;dish 套餐表&#xff1a;setmeal 套餐菜品关系表&#x…

【计算机网络】第五,六章摘要重点

1.运输层协议概述 运输层提供的是进程之间的通信 2. 3.套接字指的是什么 ip地址端口号 4.每一条TCP语句唯一地被通信两端连接的两个端点 5.TCP传输如何实现 以字节为单位的滑动窗口 超时重传 选择确认 6.TCP流量控制和拥塞控制的区别 流量控制&#xff1a;点对点通信…

SpringMVC学习与开发(四)

注&#xff1a;此为笔者学习狂神说SpringMVC的笔记&#xff0c;其中包含个人的笔记和理解&#xff0c;仅做学习笔记之用&#xff0c;更多详细资讯请出门左拐B站&#xff1a;狂神说!!! 11、Ajax初体验 1、伪造Ajax 结果&#xff1a;并未有xhr异步请求 <!DOCTYPE html> &…

vscode: make sure you configure your user.name and user.email in git

一、问题描述 使用VScode编辑代码后&#xff0c;Push到云端报错&#xff1a;Make sure you configure your "user.name" and "user.email" in git 二、解决方案 解决步骤&#xff1a; 1.打开Git Bash&#xff1a; 2.输入命令&#xff1a; git config -…

论文阅读——EfficientViT(cvpr2023)

EfficientViT: Memory Efficient Vision Transformer with Cascaded Group Attention 1、 从三个角度探讨如何提高vision transformers的效率&#xff1a;内存访问、计算冗余和参数使用。 2.1. Memory Efficiency 红色字体表示操作所花费的时间主要由内存访问决定&#xff0c;…

<JavaEE> 协议格式 -- 传输层协议 TCP

目录 一、TCP协议格式长啥样&#xff1f; 二、TCP协议属性解释 1&#xff09;源端口号/目的端口号 2&#xff09;序号/确认序号 3&#xff09;TCP报头长度 4&#xff09;保留位 5&#xff09;标志位 6&#xff09;窗口大小 7&#xff09;校验和 8&#xff09;紧急指针…

过年过节通过html+css+js代码实现:超级好看的放烟花效果(含背景音乐)

文章目录&#xff1a; 一&#xff1a;放烟花 1. 运行效果 2.代码 二&#xff1a;新年快乐 1.运行效果 2.代码 一&#xff1a;放烟花 1. 运行效果 效果图◕‿◕✌✌✌ 过年过节通过htmlcssjs实现放烟花效果代码(含背景音乐) 2.代码 修改后缀为".html"的格式…

【UE5蓝图】读取本地json文件修改窗口大小

效果 插件 蓝图 1.判断文件存在 2.1文件不存在&#xff0c;生成文件 {"ResolutionX":540, "ResolutionY":960} 2.2文件存在&#xff0c;直接读取 3.设置窗口大小 遇到的坑 1.分辨率太大&#xff0c;导致效果不理想&#xff0c;建议先往小填写。 2.选对…

Centos 7.9 升级 OpenSSH 到 openssh-9.4p1及openssl-1.1.1k

Centos 7.9 升级 OpenSSH 到 openssh-9.4p1及openssl-1.1.1k 注&#xff1a;ssh升级到openssh-9.4p1需要openssl-1.1.1及以上&#xff01;&#xff01;&#xff01; openssh-9.4p1和openssl-1.1.1下载地址 一、升级openssl 到openssl-1.1.1k 1.基础环境 首先&#xff0c;安…

【ArcGIS微课1000例】0082:地震灾害图件制作之DEM晕渲图(山体阴影效果)

以甘肃积石山县6.2级地震为例,基于震中100km范围内的DEM数据,制作数字高程模型山体阴影晕渲图。 文章目录 一、效果展示二、实验数据三、晕渲图制作一、效果展示 基于数字高程模型制作的山体阴影晕渲图如下所示: 二、实验数据 本试验所需要的数据包括: 1. 震中位置矢量数…

[Angular] 笔记 23:Renderer2 - ElementRef 的生产版本

chatgpt: Renderer2 简介 在 Angular 中&#xff0c;Renderer2 是一个服务&#xff0c;用于处理 DOM 操作的抽象层。它提供了一种安全的方式来操作 DOM&#xff0c;同时与平台无关&#xff0c;有助于维护应用程序的跨浏览器兼容性和安全性。 Renderer2 的作用是在 Angular 组…