最短路径--Dijkstra算法.

本文详细介绍Dijkstra算法原理及其应用,包括图解说明、代码实现及优先队列优化等,帮助读者掌握无权图的最短路径算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Dijkstra 图解

首先来看一张有向图
堆这个图的边描述就是edges [[0,1],[0,2],[1,2],[1,3],[2,4],[3,2],[3,4],[3,5],[4,5]](默认边带权为1
在这里插入图片描述
使用矩阵来描述如下图
在这里插入图片描述

现在我们要计算从节点0到各个节点的最短路径。

使用Dijkstra算法我们需要一张表,用来记从0到各个节点的最短路径,以及记录当前路径是不是0到这个点的最短路径。00的节点为 0,而其他未知就为无穷,所以表的初始如下图所示。
在这里插入图片描述
现在我们从节点0开始遍历,遍历的规则是找到上述表格中没有被访问过!visited且距离当前节点最进的节点distance[y] < distance[x](y为找到的节点,x为当前比较节点)

找到当前最小节点以后,就更新经过这个节点的最小距离这个节点的最小距离。

简单点说就是:每次从「未确定节点」中取一个与起点距离最短的点,将它归类为「已确定节点」,并用它「更新」从起点到其他所有「未确定节点」的距离。直到所有点都被归类为「已确定节点」。

这里我们还安排一个x = -1,用来每次找到「最短距离最小」且「未被更新」的点 x

以下是Dijkstra的遍历的核心代码,通过对下面代码的扩充我们就可以完成一些无权的最短路径算法问题。

for(int i = 0; i < n; i++){
		int x = -1;
		for(int y = 0; y < n; y++){
			if(!visited[y] && (x == -1 || distance[y] < distance[x])){
				x = y;
			}
		}
		visited[x] = true;
		for(int y = 0; y < n; y++){
		distance[y] = Math.min(distance[y], distance[x] + grid[x][y]);
	}
}

在继续往下读的时候可以尝试一下力扣的最短路径相关题目743. 网络延迟时间

如果上述代码没有弄明白可以观看一些图解视频会更加直观,而且可以使用编辑器进行代码单步执行,来理解这些核心的代码思想

3.题目代码实现

在上述的题目中,在计算之前,我们先要把图构建好

int[][] grid = new int[n + 1][n + 1];
int INF = Integer.MAX_VALUE / 2;
for(int i = 1; i  <= n; i++){
	Arrays.fill(grid[i], INF);
}
for(int[] edge : times){
	grid[edge[0]][edge[1]] = edge[2];
}

将图建好以后我们就需要进行记录表相关的初始化操作。

boolean[] visited = new boolean[n + 1];
int[] distance = new int[n + 1];
Arrays.fill(distance,INF);

接下来就可以使用核心代码来计算最小路径了。

4.优先队列优化

为什么要使用优先队列优化呢?使用优先队列,我们就可以使用广度优先搜索来计算最小路径,因为我们每一次都要找到表中当前最小的路径是哪一条,这样遍历会花费很多的时间,所有我们可以使用小顶堆来进行(优先队列)来减少这样的查找,从而解决这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值