【迪杰斯特拉算法思想】

设有两个顶点集合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. 突发!又一个程序员在东南亚出事了...
  2. 【TensorFlow2.0】数据读取与使用方式
  3. SAP Spartacus 3.0 的一些变化
  4. 周鸿祎:网络安全面前 没有国家可以袖手旁观
  5. 微信获取地理位置转城市demo
  6. Python:学习笔记之多值参数(函数中*传递元组**传递字典)案例演练
  7. Python的学习必备基础知识总结
  8. 拓端tecdat|新能源车主数据图鉴
  9. 赶快拿走!分享4款实用的软件,一般人我都不告诉他!
  10. 【线性回归】-最小二乘法求一元线性回归公式推导及代码实现
  11. Java处理wangeditor上传图片并升级一下
  12. 油猴【QQ空间自动点赞-模拟点击】
  13. 阿拉伯数字金额转换为汉语大写
  14. mysql怎么tonumber_orcale中的to_number方法使用
  15. 下拉菜单(Dropdown)
  16. ps快捷图标在哪个文件夹_在PS中制作一个下载文件夹的图标
  17. 60 Linux 常用 命令
  18. EAUML日拱一卒-微信小程序实战:位置闹铃 (9)-利用条件渲染实现列表控件
  19. 计算机二级C语言中isdigit,C使用带字符串的标准算法,带有isdigit的count_if,函数转换...
  20. 【付费阅读V5.6.1 】功能模块、付费阅读小程序源码、开源版

热门文章

  1. 百度面试过程详解-附电话面试题
  2. 2022-2028年全球与中国贴标机(印刷和贴标签及贴标设备)产业市场前瞻与投资战略规划分析
  3. swing 布局设计
  4. adidas最软的鞋_YEEZY太贵,最值得推荐的5双adidas千元潮鞋
  5. python 情书_用Python做一个520表白神器,值得收藏(示例代码)
  6. 【转】Android手机应用UI设计的10个建议
  7. 126邮箱页面源码的思考
  8. Boost(6):Boost.Python 如何转换 C++ 的参数和返回值类型
  9. 探花交友_第11章_数据统计与内容审核(新版)
  10. iphone6实际屏幕大小_5个最佳免费iPhone游戏(实际上是免费的)