1.概述

(1)与弗洛伊德(Floyd)算法一样,迪杰斯特拉(Dijkstra)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法,主要特点是以出发点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止

2. 迪杰斯特拉(Dijkstra)算法 与 弗洛伊德(Floyd)算法 的区别

(1)迪杰斯特拉(Dijkstra)算法:选定图中某一个顶点作为出发顶点,求出出发顶点到其他顶点的最短路径
(2) 弗洛伊德(Floyd)算法:图中的每一个顶点都是出发顶点,需要求出每一个被看成为出发顶点的顶点到其他顶点的最短路径

3.迪杰斯特拉(Dijkstra)算法的基本思路

(1)设置 int[] distance 记录出发点到图中各个顶点的距离,int[] preArray 记录图中各个顶点的前驱顶点,boolean[] visited 记录某个顶点是否已经被访问,LinkedList<String> linkedList 模拟队列,记录顶点的访问顺序(广度优先搜索思想 的体现),int[][] edgeArray 记录图中顶点之间的距离
(2)设置 i 为出发点,k 为由 广度优先搜索 得到的顶点,作为连接 i 与 j 的中间顶点,j 为其他顶点,如果存在 distance[k] + edgeArray[k][j] < distance[j] ,则更新 distance[j] ,即 distance[j] = distance[k] + edgeArray[k][j] ,代表 k 作为中间顶点时,出发点 i 到顶点 j 的最短距离为 distance[j] = distance[k] + edgeArray[k][j] ,这个最短距离是实时更新的,有可能通过其他中间顶点 k 得到更小的 distance[j] ,直到算法执行完毕,才会得到出发点到其他顶点的最短距离,如果 distance[k] + edgeArray[k][j] >= distance[j] , 则不做任何操作

4.代码实现

package com.zzb.algorithm.dijkstra;import java.io.Serializable;
import java.util.LinkedList;/*** @Auther: Administrator* @Date: 2020/3/28 13:20* @Description: 迪杰斯特拉算法 应用之 最短路径问题* 使用 图的广度优先搜索 解决问题*/
public class Dijkstra {public static void main(String[] args) {// 顶点值数组String[] vertexArray = {"A", "B", "C", "D", "E", "F", "G"};// 邻接矩阵final int N = Integer.MAX_VALUE/2; // 表示不可以连接int[][] matrix = new int[vertexArray.length][vertexArray.length];matrix[0]=new int[]{N,5,7,N,N,N,2};matrix[1]=new int[]{5,N,N,9,N,N,3};matrix[2]=new int[]{7,N,N,N,8,N,N};matrix[3]=new int[]{N,9,N,N,N,4,N};matrix[4]=new int[]{N,N,8,N,N,5,4};matrix[5]=new int[]{N,N,N,4,5,N,6};matrix[6]=new int[]{2,3,N,N,4,6,N};//创建Graph对象Graph graph = new Graph(vertexArray, matrix);// 出发点 到 其他顶点 的最短距离的详细信息graph.showDistanceDetail("G");/*G 到 A 的最短距离为 2 (G->A)G 到 B 的最短距离为 3 (G->B)G 到 C 的最短距离为 9 (G->A->C)G 到 D 的最短距离为 10 (G->F->D)G 到 E 的最短距离为 4 (G->E)G 到 F 的最短距离为 6 (G->F)G 到 G 的最短距离为 0 (G->G)*/}
}/*** 图类*/
class Graph implements Serializable {private static final long serialVersionUID = -6363517010637626584L;// 存储图中各个顶点的集合private String[] vertexArray;// 存储图中各条边的邻接矩阵private int[][] edgeArray;// 出发点到图中各个顶点的距离,最终得到出发点到各个顶点的最短距离,初始化为最大距离,代表各个顶点之间不连通,实时更新// 数组下标代表各个顶点的下标,数组下标对应的值为出发点到各个顶点的距离private int[] distance;// 记录图中各个顶点的前驱顶点,初始化为各个顶点的前驱顶点为自身,代表各个顶点之间不连通,实时更新// 前驱顶点理解:以某一个顶点为中心,与该顶点连通的并且是上一个顶点,记录了最短距离是由哪些顶点连通得到的// 数组下标代表某一个顶点,数组下标对应的值为前驱顶点的下标private int[] preArray;// 记录某个顶点是否已经被访问,初始化为false未被访问,数组的下标即为顶点在图中顶点集合的索引private boolean[] visited;/*** 构造器初始化** @param vertexArray 顶点* @param edgeArray 邻接矩阵*/public Graph(String[] vertexArray, int[][] edgeArray) {this.vertexArray = vertexArray;this.edgeArray = edgeArray;// 初始化为最大距离,代表各个顶点之间不连通,实时更新this.distance = new int[this.vertexArray.length];for(int i = 0; i < this.vertexArray.length; i++) {this.distance[i] = Integer.MAX_VALUE/2;}// 初始化为各个顶点的前驱顶点为自身,代表各个顶点之间不连通,实时更新this.preArray = new int[this.vertexArray.length];for(int i = 0; i < this.vertexArray.length; i++) {this.preArray[i] = i;}// 初始化为false未被访问,数组的下标即为顶点在图中顶点集合的索引this. visited = new boolean[this.vertexArray.length];}/*** 迪杰斯特拉算法*指定 出发点,求取出发点到其他顶点的最短距离** @param initVertex 出发点*/private void dsj(String initVertex) {// 存储某个顶点在图中顶点集合的对应索引int indexOfVertex;indexOfVertex = this.getIndexOfVertex(initVertex);// 设置出发点到自身的距离为0(否则计算不了出发点到其他顶点的最短距离的正确结果)this.distance[indexOfVertex] = 0;// 记录顶点的访问顺序,用linkedList模拟队列LinkedList<String> linkedList = new LinkedList<>();// 以下标为indexVertex的顶点为中心寻找出发点到各个顶点的最短距离,并且更新update(indexOfVertex, linkedList);String vertex;while(!linkedList.isEmpty()) { // 广度优先搜索算法 的体现// 获取队列的头结点vertex = linkedList.removeFirst();// 获取vertex顶点在图中顶点集合的对应索引indexOfVertex = this.getIndexOfVertex(vertex);//以下标为indexVertex的顶点为中心寻找出发点到各个顶点的最短距离,并且更新update(indexOfVertex, linkedList);}}/*** 以下标为 indexOfVertex 的顶点为中心寻找出发点到各个顶点的最短距离,并且更新** @param indexOfVertex 某个顶点的索引* @param linkedList 顶点被访问后存储到的队列*/private void update(int indexOfVertex, LinkedList<String> linkedList) {// 设置该顶点已经被访问this.visited[indexOfVertex] = true;int dis;for(int i = 0; i < this.vertexArray.length; i++) { // 遍历 indexOfVertex 顶点到各个顶点的距离dis = this.distance[indexOfVertex] + this.edgeArray[indexOfVertex][i];// 比较 由 出发点 到 indexOfVertex 顶点(distance[indexOfVertex])加上 indexOfVertex 顶点到 i 顶点(edgeArray[indexOfVertex][i])的距离// 与 出发点 到 i 顶点距离(distance[i]) 大小,判断是否要更新 出发点 到 i 顶点 的 最短距离if(!this.visited[i] && dis < this.distance[i]) {// 更新 出发点 到 i 顶点的距离this.distance[i] = dis;// 更新i顶点的前驱顶点为 indexOfVertex 顶点this.preArray[i] = indexOfVertex;// indexOfVertex 顶点 与 i 顶点 连通,并且能得到最短距离,则加入到队列中// linkedList.contains(this.vertexArray[i]) 解释: 存在vertexArray[i])顶点已经在队列中的可能// 比如A->C,C加入队列,但是往后还有一条路径A->B->C 的距离 比 A->C 的距离还短,但是C已经在队列中,不需要重复加入,// 相当于 C 被访问过了,但是真正设置某个顶点被访问过是 update 方法中的一行代码// private void update(int indexOfVertex, LinkedList<String> linkedList) {// 设置该顶点已经被访问// this.visited[indexOfVertex] = true;if(this.edgeArray[indexOfVertex][i] != Integer.MAX_VALUE/2 && !linkedList.contains(this.vertexArray[i])) {// 广度优先搜索 的体现linkedList.addLast(this.vertexArray[i]);}}}}/*** 出发点 到 其他顶点 的最短距离的详细信息* * @param initVertex 出发点*/public void showDistanceDetail(String initVertex) {// 迪杰斯特拉算法dsj(initVertex);// 后续处理,详细展示最短距离数据int indexOfInitVertex = this.getIndexOfVertex(initVertex);int tempIndex;String tempStr = "";for(int i = 0; i < this.distance.length; i++) {/*tempIndex = this.preArray[i];while(tempIndex != indexOfInitVertex) {tempStr = this.vertexArray[tempIndex] + "->" + tempStr;tempIndex = this.preArray[tempIndex];}*/tempIndex = i;while((tempIndex = this.preArray[tempIndex]) != indexOfInitVertex) {tempStr = this.vertexArray[tempIndex] + "->" + tempStr;}// 拼接tempStr = this.vertexArray[indexOfInitVertex] + "->" + tempStr + this.vertexArray[i];System.out.println(this.vertexArray[indexOfInitVertex] + " 到 " + this.vertexArray[i] + " 的最短距离为 " + this.distance[i]+ " (" + tempStr + ")");// 清空tempStr = "";}}/*** 获取各个定点所对应的索引** @param vertex 顶点所在集合的值* @return 获取各个顶点所对应的索引*/private int getIndexOfVertex(String vertex) {for(int i = 0; i < this.vertexArray.length; i++) {if(vertex.equals(this.vertexArray[i])) {return i;}}return -1;}/*** 显示图对应的邻接矩阵*/public void showGraph() {for(int i = 0; i < vertexArray.length; i++) {for(int j = 0; j < vertexArray.length; j++) {System.out.print(edgeArray[i][j] + "\t\t");}System.out.println();}}
}

5.代码运行的最终结果

G 到 A 的最短距离为 2 (G->A)
G 到 B 的最短距离为 3 (G->B)
G 到 C 的最短距离为 9 (G->A->C)
G 到 D 的最短距离为 10 (G->F->D)
G 到 E 的最短距离为 4 (G->E)
G 到 F 的最短距离为 6 (G->F)
G 到 G 的最短距离为 0 (G->G)

迪杰斯特拉(Dijkstra)算法之两点之间的最短距离问题相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    定义 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法 ...

最新文章

  1. getPath()和getResource()找不到文件(NullPointerException)的原因(idea创建properties文件)
  2. 你很烫吗?我很烫——关于栈区和静态存储区的思考
  3. 模板 字段_Anki学习之路(08)|什么是Anki模板类型?什么是字段?
  4. WriteFile写UNICODE字符串 TxT显示乱码
  5. geometry-api-java 学习笔记(三)多点 multipoint
  6. 【转载保存】什么是线程阻塞?为什么会出现线程阻塞?
  7. jQuery的内容选择器和属性
  8. 智能车学习(一)—— 硬件准备
  9. 【转】wget 使用技巧
  10. UnicodeMath编码教程
  11. activity 和service通信,调用service方法
  12. 网上购物系统数据库分析
  13. 计算机视觉论文-2021-04-06
  14. Java API II
  15. 修改vscode图标
  16. 阿里巴巴招募AI鉴黄体验官,日薪1000,小姐姐优先,快看看你是否符合
  17. Adams隐式4阶方法解常微分方程,fortran实现
  18. 重要的表格数据误删了,用EasyRecovery快速恢复!
  19. 基于c#winform的可视化打印标签模板设计器及Labview与C#调用模板Demo
  20. 神经网络机器翻译模型介绍

热门文章

  1. 阿里云发送邮件(mail)失败
  2. 树莓派 Raspberry 4B 刷机、上网、录音外设、文件传输、电脑投屏问题汇总
  3. 数字图像处理(1)-图片信息获取和RGB-HSI
  4. unraid虚拟linux系统,UNRAID教程:3分钟 用unraid自带的虚拟机 安装 黑群晖NAS DSM系统 很强大!...
  5. 2017IT在线教育机构汇总
  6. 梯形法求定积分(C)
  7. HelloChart框架动态加载数据
  8. EMERSON艾默生AMS巡检仪维修TREX通讯器维修注意事项
  9. Springboot毕业设计毕设作品,黑白图片和上色处理系统 开题报告
  10. 雷电3接口能干嘛_把雷电3插到TypeC接口了?不认识电脑接口的小伙伴看过来