给出一个图,求某个端点(goal)到其余端点或者某个端点的最短路径,最容易想到的求法是利用DFS,假设求起点到某个端点走过的平均路径为n条,每个端点的平均邻接端点为m,那求出这个最短路径使用DFS算法的时间复杂度为O(mn), 这显然是十分不理想的。

于是提出迪杰斯特拉(Dijkstra)算法,为解决有向图中某个端点到其余端点的最短路径, 在端点数为m,时间复杂度为O(m2)的情况下求出结果,前提条件是每条边的权重不能使负值。

接下来讲述算法细节:

1、把所有端点划分为两个集合,所有已找到最短路径的端点集合和未找到最短路径的端点集合(初始只有起点在已找到最短路线端点集合中)。

2、维护一个长度为m的距离数组(下面均用这个表达,都是指这个东西),存储当前所有端点的最短距离。当一个新的端点找到最短路径的时候,即更新该端点所能到达的其余未找到最短路径的端点的当前最短距离(初始值是起点到所能到达的端点的距离)。

3、循环m-1次,每次从距离数组中找到最小的数值,该数值即为该端点的最短路径(比如起点为A,遍历的时候找到最小数值是B,那么这个值就是B点的最短距离,因为不可能从A出去的其他路径再经过其他路径再到达B的距离比这个距离更小,除非有路径的权重是负值,但这与Dijkstra的前提条件相悖)。

4、对当前找到最短路径的端点,如果从该点出发,所能到达的未找到最短路径的端点小于当前距离数组里面的值,则更新这个值。

5、循环m-1次找到所有端点的最短路径,或者在某个循环未能找到符合要求的端点,则说明剩下的端点不可到达,都结束此次计算。

下面举个例子配合图例一步一步模拟这个过程

图例约定如下:

初始有向图如下:

1. 把起点A加入已找到最短距离的集合当中,并更新相应距离数组和标志位,此时找到B点距离为2,C点距离为6,E点距离为10

2. 下一步,找到距离数组的中未找到最短距离且值最小的节点。B节点距离最小,所以第二个加入到已找到最短路径的节点是B节点,然后根据从节点B出发的所有路径更新距离数组,从B到E距离是9,加上B原本的最短距离2,总共是11,但比距离数组中到达E点的的当前距离10更大,所以不需要更新E点的距离。但到达C点的距离是3,总共就是5,距离数组中到C点的距离为6,我们已经找到更短的路径了,更新这个值。

3. 接着,跟第2步同样的步骤,找到下一个最短距离是节点C,同样更新距离数组和标志位,接着是节点D,然后是节点E,至此所有节点都被添加到已找到最短路径集合当中,算法结束

整个过程如图所示,接下来就是写代码咯

1 //calculate the shortest distance from start point to end point

2 public void calcDistance(int start, int[][] matrix) {3 this.matrix =matrix;4 this.start =start;5 int cnt = matrix.length; //Point count

6 this.goalCnt =cnt;7 boolean[] found = new boolean[cnt]; //true value indicate the shortest distance from start to n have been found

8 int[] dis = new int[cnt]; //store the shortest distance from start to n, initial as INT_MAX

9 int[] preRoute = new int[cnt]; //preRoute[u] = v represent that the previous goal of shortest path to u is v

10 for (int i = 0; i < cnt; i++) {11 dis[i] = start == i ? 0 : matrix[start][i] != 0 ?matrix[start][i] : Integer.MAX_VALUE;12 preRoute[i] = -1;13 }14 found[start] = true;15 //find out one shortest path in one iteration

16 for (int i = 0; i < cnt - 1; i++) {17 //the shortest distance of the index of goal was found in current iteration

18 int tDis =Integer.MAX_VALUE,19 tInd = -1;20 for (int j = 0; j < cnt; j++) {21 if (!found[j] && dis[j]

28 break;29 }30 found[tInd] = true;31 distance.put(tInd, dis[tInd]);32 //find out the route of the tInd goal

33 int e =tInd;34 Stack stack = new Stack<>();35 while (-1 !=e) {36 stack.push(e);37 e =preRoute[e];38 }39 route.put(tInd, stack);40 //update the shorter path

41 for (int j = 0; j < cnt; j ++) {42 if (matrix[tInd][j] != 0) {43 int newDis = dis[tInd] +matrix[tInd][j];44 if (!found[j] && newDis

47 }48 }49 }50 }51 }

以上为Dijkstra的核心算法,传入一个图一个起点,求出这个起点到其余端点的最短路径,found[n]为true表示下标为n的端点的最短路径已经找到,dis数组即为上文所提距离数组,32~39行以及preRoute数组只是为了找出路径所经节点,不属于算法内容。

下面我们找一张图检验一下算法结果,S(N0)为起点。

化为矩阵形式如下:

public static voidmain(String[] args) {//test data

int[][] matrix ={

{0,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{3,0,1,0,1,0,0,0,0,4,0,0,0,0,0,0,0,0},

{1,1,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0},

{1,0,1,0,0,2,2,1,0,0,0,0,0,0,0,0,0,0},

{0,1,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0},

{0,0,1,2,1,0,1,0,0,3,1,0,3,0,0,0,0,0},

{0,0,0,2,0,1,0,1,2,0,0,0,2,4,3,0,0,0},

{0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,2,1,0,0,0,0,0,0,1,3,0,0},

{0,4,0,0,1,3,0,0,0,0,1,1,0,0,0,0,0,0},

{0,0,0,0,0,1,0,0,0,1,0,1,2,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,1,0},

{0,0,0,0,0,3,2,0,0,0,2,1,0,2,0,0,1,0},

{0,0,0,0,0,0,4,0,0,0,0,0,2,0,1,2,2,1},

{0,0,0,0,0,0,3,0,1,0,0,0,0,1,0,1,0,0},

{0,0,0,0,0,0,0,0,3,0,0,0,0,2,1,0,0,4},

{0,0,0,0,0,0,0,0,0,0,0,1,1,2,0,0,0,1},

{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,4,1,0}};

Dijkstra dijkstra= newDijkstra();

dijkstra.calcDistance(0, matrix);for (int i = 1; i < dijkstra.getGoalCnt(); i++) {

System.out.println("Destination: " +i);

System.out.println("Distance: " +dijkstra.getDistance(i));

System.out.println("Path: " +dijkstra.getRouteMap(i));

System.out.println();

}

}

运算结果:

Destination: 1Distance:2Path:0->2->1Destination:2Distance:1Path:0->2Destination:3Distance:1Path:0->3Destination:4Distance:3Path:0->2->4Destination:5Distance:2Path:0->2->5Destination:6Distance:3Path:0->3->6Destination:7Distance:2Path:0->3->7Destination:8Distance:3Path:0->3->7->8Destination:9Distance:4Path:0->2->4->9Destination:10Distance:3Path:0->2->5->10Destination:11Distance:4Path:0->2->5->10->11Destination:12Distance:5Path:0->2->5->12Destination:13Distance:5Path:0->3->7->8->14->13Destination:14Distance:4Path:0->3->7->8->14Destination:15Distance:5Path:0->3->7->8->14->15Destination:16Distance:5Path:0->2->5->10->11->16Destination:17Distance:6Path:0->3->7->8->14->13->17

初步检验结果是正确的。

至此,以上为个人对Dijkstra算法的理解,如有不妥之处,欢迎指出斧正。

尊重知识产权,转载引用请通知作者并注明出处!

单源最短路径算法java_数据结构 - 单源最短路径之迪杰斯特拉(Dijkstra)算法详解(Java)...相关推荐

  1. 数据结构与算法(7-4)最短路径(迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)

    目录 一.最短路径概念 二.迪杰斯特拉(Dijkstra)算法(单源最短路径) 1.原理 2.过程 3.代码 三.弗洛伊德(Floyd)算法(多源最短路径) 1.原理 2.存储 3.遍历 4.代码 参 ...

  2. 数据结构——图——迪杰斯特拉(Dijkstra )算法

    数据结构--图--迪杰斯特拉(Dijkstra )算法 这是一个按路径长度递增的次序产生最短路径的算法.它的思路大体是这样的. 比如说要求图7-7-3中顶点v0到顶点v1的最短距离,没有比这更简单的了 ...

  3. 059.迪杰斯特拉(Dijkstra)算法的原理以及解决最短路径问题

    1. 迪杰斯特拉(Dijkstra)算法的原理 1.1. 算法应用场景-最短路径问题 1.2. 基本介绍 1.3. 步骤详解 1.4. 思路解析 1.5. 图解步骤 2. 迪杰斯特拉(Dijkstra ...

  4. java数据结构和算法——迪杰斯特拉(Dijkstra)算法

    目录 一.迪杰斯特拉(Dijkstra)算法介绍 二.迪杰斯特拉(Dijkstra)算法过程 三.迪杰斯特拉(Dijkstra)算法--应用场景(最短路径问题) 四.迪杰斯特拉(Dijkstra)算法 ...

  5. 迪杰斯特拉(Dijkstra)算法解决最短路径问题

    Dijkstra 算法介绍 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.迪杰斯特拉(Dijkstra)算法是最经典的最短路径算法之一,用 ...

  6. 最短路径算法-迪杰斯特拉(Dijkstra)算法

    最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思 ...

  7. java实现迪杰斯特拉(Dijkstra)算法求解最短路问题

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的.是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题. 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分 ...

  8. Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法

    1.Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法 1.1 迪杰斯特拉(Dijkstra)算法 1.1.1 迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra ...

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

    迪杰斯特拉(Dijkstra)算法详解 在讲解迪杰斯特拉算法之前先讲解一下什么是最短路径: [图一] 假如我要求从A点到D点的最短路径,我们用肉眼可以很快速找出A–>C–>E–>D就 ...

  10. 最短路径 - 迪杰斯特拉(Dijkstra)算法

    对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点.最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd ...

最新文章

  1. foo php,php – $foo === TRUE和TRUE === $foo有什么区别?
  2. 算法与数据结构 - 滑动窗口
  3. 聚类分析(Clustering Analysis)
  4. 启明云端分享|由于国外某品牌WIFI缺货涨价,导致Ipcamera、机顶盒及一些商显、广告机厂商生产跟不上,成本直线上升,怎么办呢,替代方案来了,选用pin to pin的ESP8089模块就可以了
  5. 74cms 注入exp
  6. android listview 异步加载问题
  7. 九个工作谎言_书评:关于工作的九种谎言
  8. CCF202012-2 期末预测之最优阈值
  9. hdu 1800 Flying to the Mars
  10. JQuer实战第一讲:验证用户名是否可用
  11. (转载)年薪如何从10万跳到50万
  12. 从简单的 XSS 到完整的 Google Cloud Shell 实例接管,值5000美元
  13. Spring - Netty (整合)
  14. 蓝桥杯2013c++真题:排它平方数
  15. 一款开源Android在线音乐播放器
  16. launcher3的具体学习
  17. OOM and SOF
  18. 3des解密 mysql_转角处拐弯007
  19. 梁定郊:一个人行贿赠西藏、新疆狂 野之旅
  20. Elasticsearch Query DSL 整理总结(查询)

热门文章

  1. 自动滑动背景图片html,html背景图片滚动属性bgproperties
  2. wireshark抓组播数据_wireshark过滤?wireshark 看端口号?wireshark组播包?WireShark 过滤语法...
  3. C#选择文件、选择文件夹、打开文件(或者文件夹)
  4. QUECTEL上海移远4G通讯CAT4模组EC20CEFAG模块串口调试指南之03EC20模组基础串口指令说明
  5. python 创建和使用字典
  6. android集成科大讯飞语音听写和语音合成
  7. 9.Java SE 集合
  8. 广州智算科技有限公司前端面试题
  9. .Net混淆工具和反混淆工具
  10. 高等代数----最小多项式的矩阵表示