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

这篇具有很好参考价值的文章主要介绍了堆优化版迪杰斯特拉(Dijkstra)算法简单分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

  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为当源点

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

 文章来源地址https://www.toymoban.com/news/detail-402184.html

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

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

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

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

依次类推得:

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

 时间复杂度分析

每次找到最小距离的点沿着边更新其他的点,若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)算法简单分析

 

到了这里,关于堆优化版迪杰斯特拉(Dijkstra)算法简单分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • dijkstra迪杰斯特拉算法(邻接表法)

    算法简易过程: 求单源有向图最短路径 使用 邻接表法 来存储顶点和边,录入 有向图 。 (当然也可以无向图,不过录入时要录入两次,比如 a b 3        b a 3)  代码如下: 测试如下:  

    2024年02月07日
    浏览(42)
  • C语言 最短路径 迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中单源最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最

    2024年02月03日
    浏览(40)
  • java实现迪杰斯特拉(Dijkstra)算法求解最短路问题

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的。是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题。 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分为已标记点和未标记点两个集合,从起始点开始,不断在未标记点中寻

    2024年02月12日
    浏览(37)
  • 【数据结构】图解:迪杰斯特拉算法(Dijkstra)最短路径

    目录 一、方法描述 二、例题一  ​编辑 三、例题二  有图如上,用迪杰斯特拉算法求顶点A到其余各顶点的最短路径,请问1.第一步求出的最短路径是A到C的最短路径2.第二步求出的是顶点A到顶点B/F的最短路径3.顶点A到D的最短路径长度是__25___ (填数字)4.顶点A到顶点F的最短路

    2024年02月12日
    浏览(35)
  • 大话数据结构-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

      最短路径,对于图来说,是两顶点之间经过的边数最少的路径;对于网来说,是指两顶点之间经过的边上权值之和最小的路径。路径上第一个顶点为源点,最后一个顶点是终点。   以如下无向图为例:   我们来计算下标为0的顶点,到其他顶点的最短路径,首先定义

    2024年02月06日
    浏览(39)
  • 数据结构 -最短路径dijkstra(迪杰斯特拉)算法讲解及代码实现

            迪杰斯特拉算法是一种广义的贪心算法,求出局部最优解,再去求全局最优解 举例图:(起始点为1) 辅助数组: s:记录了目标顶点到其他顶点的最短路径是否求得(求得为1,否则为0) p:目标顶点到其他顶点的最短路径的前驱节点 (如,求得1-7-5的最短路径,那

    2024年02月11日
    浏览(35)
  • MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    利用MATLAB绘制地图需要三个基本数据: 节点 节点坐标 节点间相通的路线 以11B交通巡警平台调度问题中的A区数据为例: (数据及工程文件下载链接见文末) Demo1: 可通过已知节点的坐标,计算出各节点之间的距离,有Matlab基础的同学可以尝试Demo2, 也可通过Excel自行实现;

    2023年04月21日
    浏览(47)
  • 数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现

    目录 前言 1. 介绍 2. 加权图 2.1 概念 3. 最短路径 -- Dijkstra 算法 3.1 历史 3.2 Dijkstra 算法的基本思路 3.3 Dijkstra 算法图解 4.  python中dijkstra算法的实现 5. 总结  前两章我们讲到了关于图的基本知识,和广度/深度优先搜索。 本章,我们将介绍 加权图 和 最短路径 的相关知识。 最

    2024年02月12日
    浏览(51)
  • 迪杰斯特拉(Dijkstra's )算法——解决带权有向无向图最短路径

    迪杰斯特拉算法(Dijkstra\\\'s Algorithm),又称为狄克斯特拉算法,是一种用于解决带权重有向图或无向图最短路径问题的算法。该算法由荷兰计算机科学家艾兹赫尔·狄克斯特拉在1956年发明,是一种广泛应用于网络路由和其他领域的算法。 在 2001 年的一次采访中,Dijkstra 博士透露

    2024年02月03日
    浏览(45)
  • 使用omp并行技术加速最短路径算法-迪杰斯特拉(Dijkstra)算法(记录最短路径和距离)

    原理: Dijkstra算法是解决**单源最短路径**问题的**贪心算法** 它先求出长度最短的一条路径,再参照该最短路径求出长度次短的一条路径     直到求出从源点到其他各个顶点的最短路径。 首先假定源点为u,顶点集合V被划分为两部分:集合 S 和 V-S。 初始时S中仅含有源点u,

    2024年02月10日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包