堆优化版迪杰斯特拉算法:

  1. 优化原理:

上面的朴素版迪杰斯特拉算法主要缺陷是,每当找到一个最短路径,如果需要找下一个最短路径,就需要在完成松弛操作之后,遍历dist数组,寻找其中的最小值。遍历dist数组的时间复杂度为O(n)。(dist数组储存源点到各个点的当前最短距离)

如果图的边数为n*(n-1),那么每找到一个最小值,所要进行的松弛操作数就是n-1,这和遍历dist数组可以同时进行,算法优化的空间不大。

然而,如果是稀疏图,每找到一个最小值,所要进行的松弛操作数就远小于n-1,这时就可以对算法进行优化。优化的关键是省去对dist的线性查找,如果每次可以直接返回dist中的最大值,就可以大大减小算法的时间复杂度。

堆优化后的迪杰斯特拉算法复杂度为mlogn

  1. 算法分析:

堆优化版迪杰斯特拉时间复杂度为O(mlogn),n表示点数,m表示边数

  • 初始化dist[1]=0,dist[i]=+∞ (除1外其它点)

    • 循环遍历所有节点
    1. 找到当前未在s中标记过且离远点最近的点 (朴素:总共n^2次)---->(堆优化:总共n次)
    2. 该点进行标记
    3. 用t更新其它点的距离(朴素:O(n^2))----->(堆优化:O(mlogn))

假设1为当源点

  • 找到当前标记过且离源点最近的1号点
  • 标记1号点已确定的最短距离
  • 用1号点的距离更新2号与3号点的距离

  • 找到当前为标记过且离源点最近的2号点
  • 找到2号以确定最段距离
  • 用1号点的距离更新2号点与3号点(1+9<12)距离

依次类推得:

时间复杂度分析

每次找到最小距离的点沿着边更新其他的点,若dist[j] > distance + w[i],表示可以更新dist[j],更新后再把j点和对应的距离放入小根堆中。由于点的个数是n,边的个数是m,在极限情况下(稠密图m=n(n−1)2m=n(n−1)2)最多可以更新m回,每一回最多可以更新n个点(严格上是n - 1个点),有m回,因此最多可以把n2个点放入到小根堆中,因此每一次更新小根堆排序的情况是O(log(n2)),一共最多m次更新,因此总的时间复杂度上限是 O(mlog((n2)))=O(2mlogn)=O(mlogn)

算法代码

 public class Main{  static int N = 100010;  static int n;  static int[] h = new int[N];  static int[] e = new int[N];  static int[] ne = new int[N];  static int[] w = new int[N];  static int idx = 0;  static int[] dist = new int[N];// 存储1号点到每个点的最短距离  static boolean[] st = new boolean[N];  static int INF = 0x3f3f3f3f;//设置无穷大  public static void add(int a,int b,int c)  {  e[idx] = b;  w[idx] = c;  ne[idx] = h[a];  h[a] = idx ++;  }  // 求1号点到n号点的最短路,如果不存在则返回-1  public static int dijkstra()  {  //维护当前未在st中标记过且离源点最近的点  PriorityQueue<PIIs> queue = new PriorityQueue<PIIs>();  Arrays.fill(dist, INF);  dist[1] = 0;  queue.add(new PIIs(0,1));  while(!queue.isEmpty())  {  //1、找到当前未在s中出现过且离源点最近的点  PIIs p = queue.poll();  int t = p.getSecond();  int distance = p.getFirst();  if(st[t]) continue;  //2、将该点进行标记  st[t] = true;  //3、用t更新其他点的距离  for(int i = h[t];i != -1;i = ne[i])  {  int j = e[i];  if(dist[j] > distance + w[i])  {  dist[j] = distance + w[i];  queue.add(new PIIs(dist[j],j));  }  }  }  if(dist[n] == INF) return -1;  return dist[n];  }  public static void main(String[] args) throws IOException{  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  String[] str1 = reader.readLine().split(" ");  n = Integer.parseInt(str1[0]);  int m = Integer.parseInt(str1[1]);  Arrays.fill(h, -1);  while(m -- > 0)  {  String[] str2 = reader.readLine().split(" ");  int a = Integer.parseInt(str2[0]);  int b = Integer.parseInt(str2[1]);  int c = Integer.parseInt(str2[2]);  add(a,b,c);  }  System.out.println(dijkstra());  }
}

堆优化版迪杰斯特拉(Dijkstra)算法简单分析相关推荐

  1. 堆优化版迪杰斯特拉算法

    先是朴素版的迪杰斯特拉算法 存储结构为邻接矩阵 int dijstra(int n) {for (int i = 1; i <= n; i++){dist[1] = 0;int index = ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. (转载)从无知到有知
  2. Java-第三章-使用if选择结构实现,如果年龄够7岁或5岁并且是男,可以搬桌子
  3. mysql zf,mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI的含义
  4. 安装Uikit时ERROR in Entry module not found: Error: Can't resolve './src' in 'xxx'的解决思路
  5. java 静态对象赋值_基于Java class对象说明、Java 静态变量声明和赋值说明(详解)...
  6. .NET架构开发应知应会
  7. linux-组管理-添加组-删除组
  8. readline/readline.h: No such file or directory
  9. 新IT运维时代 | Docker运维之最佳实践-上篇
  10. python学习之dict的items(),values(),keys()
  11. vb登录ftp服务器并打开文档,VB.Net实现登陆Ftp的方法
  12. 为什么div设置其border无效?
  13. python可以下载百度文库的文档_Python 文档
  14. 音乐类软件LoveMusic开发(三)----登录界面
  15. 经典的面板数据集(R语言包plm)
  16. HTTP详解(更新完结)
  17. Keil5开发工具 --- 背景颜色绿色护眼
  18. 烧录flash_烧录固件完成后,配置JFLASH让程序自动运行
  19. 每日TED What we don't understand about trust
  20. 川崎机器人here指令_川崎机器人常用编程大法解析——川崎机器人

热门文章

  1. BMS-Pro电池巡检综合监控系统
  2. 泛函分析——内积空间定义的概念
  3. python中字符串前的 u, r/R, b的含义
  4. 游戏制作之路(25)Camera(摄像机)的清除标志Solid color
  5. 天池比赛:工业蒸汽量预测
  6. MT6261芯片处理器性能特点资料介绍
  7. 大病众筹平台会成为下一个“网络诈骗”工具吗?
  8. SpringBoot 3.0 来啦!
  9. Hbase Region的切分与合并【原理分析】
  10. Python 爬虫下载喜马拉雅音频文件