【迪杰斯特拉算法思想】

设有两个顶点集合S和T,集合S中存放图中已找到最短路径的顶点,集合T存放图中剩余顶点。初始状态下,集合S中只包含源点V0。然后不断从集合T中选取到顶点V0路径长度最短的顶点Vu并入集合S中。集合S中每次并入一个新的顶点Vu后,都要修改顶点V0到集合T中顶点的最短路径长度值。不断重复此过程,直到集合T中的顶点全部并入集合S中为止。

【深入理解】

当集合T中的顶点Vu并入集合S中时,Vu被确定为最短路径上的顶点,此时Vu就像V0到达集合T中顶点的中转站,即从V0到集合T中顶点的路径条数随着顶点Vu从集合T并入到集合S中后会增加,而这些新出现的路径很有可能比原有的V0到集合T中的顶点的路径长度小,因此需要修改原有V0到集合T中的其他顶点的路径长度。对于此时集合T中的顶点Vk来说,V0不经过Vu到Vk的路径长度(即原有的路径长度)为a,另一种是V0经过Vu到Vk的路径长度(即新的路径长度)为b。此时存在两种情况:

第一:a <= b。此时什么都不做。

第二:a > b。则用b来代替a作为V0到Vk的路径长度。

【实现迪杰斯特拉算法的辅助数据结构】

为了实现迪杰斯特拉算法,需要用到3个辅助数组:dist[]、path[]和set[]。

dist[Vi]表示当前已找到的从V0到每个终点Vi的最短路径长度。初始状态:若从V0到Vi有边,则dist[Vi]为边上的权值,否者置dist[Vi]为无穷大。

path[Vi]中保存V0到Vi最短路径上Vi的前一个顶点。假设最短路径上的定点序列为V0,V1,V2,......,Vi-1,Vi,则path[Vi] = Vi-1。初始状态:如果V0到Vi有边,则path[Vi] = V0,否则path[Vi] = -1。

set[]数组为标记数组。set[Vi] = 0 表示顶点Vi在集合T中,即没有被并入最短路径;set[Vi] = 1 表示顶点Vi在集合S中,即已经被并入最短路径。初始状态:set[V0] = 1,其余元素全为0。

【迪杰斯特拉算法的执行过程】

① 从当前的dist[]数组中选出最小值,即为当前的最短路径,假设为dist[Vu]。将set[Vu]的值设置为1,代表将当前的顶点Vu从集合T中并入到集合S中。

② 循环扫描图中的顶点,对每个顶点进行以下检测:

假设当前结点为Vj,检测Vj是否已经被并入到集合S中,即检查set[Vj]的值是否为1。如果set[Vj]的值为1,则代表顶点Vj已经被并入到集合S中,什么操作都不做。如果set[Vj]的值为0,则代表当前的顶点j还没有被并入到集合S中。此时比较dist[Vj]和dist[Vu]+w的值的大小,其中w为边<Vu,Vj>的权值。这个比较就是要看V0旧的最短路径到达Vj和V0经过含有Vu的新的路径到达Vj哪个更短一些。如果dist[Vj]>dist[Vu]+w,则用新的路径长度更新就的最短路径长度,并把顶点Vu加入到路径中,且作为路径上Vj之前的那个顶点;否则,什么都不做。

③ 对①和②步操作执行n-1次(n为图中顶点的个数),即可得到顶点V0到其余各个顶点的最短路径。

【对迪杰斯特拉算法执行过程的不充分析】

当迪杰斯特拉算法执行完毕后,path[]数组中其实保存了一棵树,这是一棵用双亲存储结构存储的树。通过这棵树可以打印出从源点到任何一个顶点最短路径上所经过的所有顶点。树的双亲表示法只能直接输出由叶子结点到根结点路径上的结点,而不能逆向输出,因此需要借助一个栈来实现逆向输出,打印路径。

【逆向打印路径函数伪代码——参考自《数据结构高分笔记》】

public void PrintPath(int path[],int a){int stack[maxsize];int top = -1;//这个循环以由叶子结点到根结点的顺序将其入栈while(path[a] != -1){stack[++top] = a;a = path[a];}stack[++top] = a;while(top != -1)System.out.println(stack[--top]);
}

【迪杰斯特拉算法实现伪代码——参考自《数据结构高分笔记》】

/*
* MGraph g:表示用邻接矩阵存储的图
* int v:表示求从顶点v到其余各个顶点的最短路径长度
* int dist[]:图中各个顶点的最短路径
* int path[]:图中各个顶点的前置结点
*
* 函数执行完毕后,dist数组中存放了v到其余各个顶点的最短路径长度。path数组中存放了v到其余各个顶点的最短路径
*/
public void Dijkstra(MGraph g,int v,int dist[],int path[]){int set[maxsize];    //设置集合数组for(int i = 0;i < g.n;++i){       //对数组进行初始化操作dist[i] = g.edges[v][i];   //dist数组的初始状态为邻接矩阵中<v,i>的值set[i] = 0;        //set数组默认初始状态均为0,表示目前图中所有顶点均在集合T中if(g.edges[v][i] < INF)      //path数组初始状态,如果顶点v与顶点i有边相连,则path[i]=v;否则path[i]=-1;path[i] = v;elsepath[i] = -1;}set[v] = 1;     //此时将顶点v加入到集合S中path[v] = -1;   //将顶点v作为树的根结点for(int i = 0;i < g.n;++i){      int min = INF; //设置最小值int min_index = -1;     //设置最小值数组下标for(int j = 0;j < g.n;++j){        //通过这个循环每次从剩余顶点中选出一个顶点,使得dist[i]的值最小if(set[j]==0 && dist[j] < min){min_index = j;min = dist[j];}set[min_index] = 1;      //将选出的顶点并入到最短路径集合S中}for(int j = 0;j < g.n;++j){       //将刚并入到集合S中的顶点作为中间点,对所有通往剩余顶点的路径进行检测,并更新最短路径if(set[j]==0 && dist[min_index]+g.edges[u][j] < dist[j]){dist[j] = dist[min_index]+g.edges[u][j]; //更新当前顶点的最短路径长度path[j] = min_index;    //将中间点min_index作为此时顶点的前置顶点}}}
}

【迪杰斯特拉算法的时间复杂度分析】

算法的主要部分为一个双重循环,基本操作执行的总次数即为双重循环执行的次数n^2次,因此迪杰斯特拉算法的时间复杂度为O(n^2)。

利用迪杰斯特拉算法求某一顶点到其余各顶点的最短路径相关推荐

  1. C++迪杰斯特拉算法求最短路径

    一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...

  2. Dijkstra(迪杰斯特拉)算法求单源最短路径问题

    Dijkstra(迪杰斯特拉)算法求单源最短路径问题 重要的事情说三遍:代码不是我写的!代码不是我写的!代码不是我写的! 第一个算法是严蔚敏数据结构(C语言版)上写的,第二个算法是王道数据结构上写的, ...

  3. c语言迪杰斯特拉算法求最短路径,迪杰斯特拉 ( Dijkstra ) 最短路径算法

    迪杰斯特拉算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径.它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本 ...

  4. POJ 3255(迪杰斯特拉算法求次短路)

    POJ3255,问题是求节点1到n的次短路. 在dijkstra求最短路算法的基础上进行变形,用两个数组分别记录源点到各节点最短路径和次短路径: 每次更新时,都将最短路的节点及可能成为次短路的节点pu ...

  5. 迪杰斯特拉算法求经纬度坐标的最短路径_【图的最短路径】迪杰斯特拉算法求图的最短路径...

    #include using namespace std; const int INFINITY=23678; const int M=3; /*typedef struct G { int ver[ ...

  6. 迪杰斯特拉算法求经纬度坐标的最短路径_Postgresql构建经纬度查询两点之间的最短路径...

    前言 前段时间遇到了实际的需求,在特定的路网中查询最短路径.同时配合 Cesium 进行动态显示. 需求 动态查询两点之间的最短路径(起点固定): 查询的路径高亮显示: Cesium 对生成的路径进行 ...

  7. 迪杰斯特拉算法——最短路径

    分析过程: 需要构建的有向图和最短路径 分析每次取出里面的最短路径 程序执行的过程: 代码块: 迪杰斯特拉算法 : #include<stdio.h> #include<string ...

  8. 校园导游系统_C语言实现_Dijkstra(迪杰斯特拉算法)_数据结构

    西京学院导游系统 摘要   要完成对整个导游图系统的功能实现,需要对每一项功能都有清楚的设想和认识,了解并明确每一项功能的实现和需要解决的问题,选择正确并且高效的算法把问题逐个解决,最终实现程序的正确 ...

  9. 迪杰斯特拉算法c语言6,C语言迪杰斯特拉实现最短路径算法.doc

    数据结构课程设计报告 ----旅游咨询系统设计 目录 一.需求分析- 2 - 二.系统分析- 2 - 三.概要设计- 3 - 一.系统划分- 3 - 二.邻接矩阵建立流程图:- 3 - 三.迪杰斯特拉 ...

最新文章

  1. 2022互联网大厂薪资大比拼
  2. mysql sql模式_MySQL SQL模式特点汇总
  3. 三电平igbt死区时间计算_基于大功率三电平IGBT模块并联的参考设计
  4. SQLServer:执行计划
  5. MySQL安装到mac还是linux_MySql在Linux下安装和Mac下的配置
  6. 11.1-12.31推荐文章汇总
  7. pyodbc-操作SQLserver
  8. 创业19年的湖南竞网如何拥抱数字化转型,按下成长加速键?
  9. qt实现扫雷游戏一:算法实现
  10. Word学习简单笔记(2)文档排版与设计
  11. ps之一寸照片的制作详解(1)
  12. 调教ChatGPT提取公众号封面
  13. 怎么对10亿个电话号码进行去重
  14. 轻松实现即席查询,Smartbi满足用户多样分析需求
  15. 如何制作prezi swf格式字体(prezi 中文字体)
  16. (4)基于UR5的DH参数建模实例
  17. 瑞吉外卖项目笔记+踩坑1——基础功能
  18. 商业公司主导下的非营利开源软件基金会之 ———— Eclipse 的成长和发展(上)...
  19. 1532. 最近的三笔订单 1543. 产品名称格式修复 1549. 每件商品的最新订单 1555. 银行账户概要
  20. PADS VX2.8 过孔盖油与不盖油的设置方法

热门文章

  1. 直通车如何快速涨质量分到10分【全平台erp、进销存软件】
  2. 弘辽科技:直通车和引力魔方组合拳打赢翻身仗
  3. 大数据技术解决了征信产生的问题,征信由哪两部分组成?
  4. 增强云服务器的安全的措施有哪些
  5. 无限远校正显微镜 物镜的放大倍数如何计算?
  6. 担心隐私泄露?Dline打造可信社交
  7. 4.9 论文笔记 |【USENIX 2020】That Was Then, This Is Now
  8. 9. solidity 常数 constant 与 immutable
  9. 真正的AI实时换脸技术——可用于直播换脸带货
  10. 软件测试常见术语(英-汉)收藏好随时备用!