(迪杰斯特拉)Dijkstra算法详细讲解

在这里插入图片描述

  1. 迪杰斯特拉算法的朴素写法

我们用这个图来模拟一下迪杰斯特拉算法,其实这个算法就是贪心加上广搜,理解了感觉非常简单

​ 贪心体现在哪呢? 广搜又体现在哪呢?

下面我们就来模拟一遍这个算

法的朴素写法,写完朴素写法之后我们试着对其优化。

此算法主要是解决,在一个图中,某一节点(start表示)到其余的节点的最短路径和距离。

算法维护着三个数组:

  • ​ dis[] : dis[i] 表示starti这个节点的最短距离

  • ​ visit[] :visit[i]= true 表示i这个节点已经被访问过之后就不需要访问了 ,这也是贪心算法体现之处

  • ​ pre[]: pre[i] = j 表示到 i节点的最短路径中i的前驱节点是j

    算法开始初始化:

  •   	初始化dis数组全为无穷大,表示目前到此节点不可达,为了以后更新所用,但是 dis[start] = 0,因为自己到自己永远是直接  可达的, 不需要寻找,  
    
  •   	初始化 visit数组全为false,表示都没有访问过
    
  •   	初始化 pre数组全为负无穷,表示 前驱节点目前不存在(不一定是负无穷,不存的数皆可)
    

算法一共分为两步:

  1. 从dis数组中找出最小路径的节点,设置此节点为已访问

  2. 对第一步找到的节点(用p表示),根据此节点邻接节点(用t表示)对dis数组进行更新,怎么更新呢?

  3. dis数组的含义是start节点到其他节点的最短路径,那么我们就可以这样更新:

    dis[p]+ map[p][i] < dis[i]时,dis[i]= dis[p]+ map[p][i] ,这个怎么理解呢,就是如果到t节点是从p节点再到t节点比我之前的那条路径到t节点还要短,那我么我们就要更新.更新完之后循环 第一步,直到所有节点都被访问过

​ 好,理解完概念之后,我们用左边的图模拟一下迪杰斯特拉算法的步骤:(假如我们要寻找1到其余三个节点的最短路)

​ 初始化 :
dis[]= [65525, 0, 65525, 65525, 65525]

visit[] =[false, false,false, false, false]

pre[] = [-1,-1,-1,-1,-1]

​ 算法循环开始

  1. 第一步 : 找最小值 可以看到 node= 1,设置visit[i]= true

​ 第二步: 以1节点进行扩展 扩展之后 dis = [65525, 0, 1, 65525, 4] pre = [-1, -1, 1, -1, 1]

  1. 第一步: 找最小值 可以看到 没有被访问过并且最小值为 node= 2 ,设置visit[2]= true

​ 第二步:更新操作,以二节点进行更新 扩展之后dis = [65525, 0, 1, 2, 4] pre = [-1, -1, 1, 2, 1]

  1. 第一步:找最小值 可以看到 没有被访问过并且最小值为 node= 3 ,设置visit[3]= true

​ 第二步:更新操作,以三节点进行更新扩展之后dis= [65525, 0, 1, 2, 3] pre = [-1, -1, 1,2, 3]

  1. 第一步:找最小值 可以看到 没有被访问过并且最小值为 node= 4 ,设置visit[4]= true

​ 第二步:更新操作 ,以四节点进行更新扩展之后dis= [65525, 0, 1, 2, 3] pre = [-1, -1, 1,2, 3]

第四步之后算法结束

如果你理解了上面步骤,那么代码应该是水到渠成了

// times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
	// time表示边关系 N表示有多少个节点 K表示从哪个节点开始寻找最短路径
	public void networkDelayTime(int[][] times, int N, int K) {
   
		HashMap<Integer, List<int[]>> map = new HashMap<>();

		// 这是无向图
        // 邻接表存储
		for (int[] t : times) {
   
			if (!map.containsKey(t[0])) {
   
				map.put(t[0], new ArrayList<int[]>());
			}
			if (!map.containsKey(t[1])) {
   
				map.put(t[1], new ArrayList<int[]>());
			}
			map.get(t[0]).add(new int[] {
    t[1], t[2] });
			map.get(t[1]).add(new int[] {
    t[0], t[2] });
		}

		System.out.println(map);
		
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
迪杰斯特拉最短路径算法是一种经典的单源最短路径算法,用于解决带权重的有向图或无向图,从一个源点到其他所有顶点的最短路径问题。 算法的基本思想是通过逐步扩展离源点越来越近的顶点的方式,逐步确定源点到其他顶点的最短路径。具体实现时,需要维护两个集合S和V-S,其S表示已经确定最短路径的顶点集合,V-S表示还未确定最短路径的顶点集合。初始时,S只包含源点,V-S包含其他所有顶点。然后,每次从V-S选择一个距离源点最近的顶点u加入到S,并更新源点到其它顶点的距离。 下面是Python实现迪杰斯特拉最短路径算法的代码,以邻接矩阵表示的有向图为例: ```python import sys def dijkstra(graph, src): n = len(graph) dist = [sys.maxsize] * n # 记录源点到各个顶点的距离 visited = [False] * n # 标记顶点是否已加入S集合 dist[src] = 0 # 初始化源点到自身的距离为0 for _ in range(n): # 找到距离源点最近的未加入S集合的顶点 u = -1 min_dist = sys.maxsize for i in range(n): if not visited[i] and dist[i] < min_dist: u = i min_dist = dist[i] if u == -1: break visited[u] = True # 更新源点到所有邻居顶点的距离 for v in range(n): if not visited[v] and graph[u][v] != 0: dist[v] = min(dist[v], dist[u] + graph[u][v]) return dist # 有向图的邻接矩阵表示 graph = [[0, 10, 3, 0, 0], [0, 0, 1, 2, 0], [0, 4, 0, 8, 2], [0, 0, 0, 0, 7], [0, 0, 0, 9, 0]] print(dijkstra(graph, 0)) # 输出从源点0到其他各个顶点的最短距离 ``` 该代码,dijkstra函数的参数graph是邻接矩阵表示的有向图,src是源点的索引。在dijkstra函数,首先初始化源点到各个顶点的距离dist和标记顶点是否已加入S集合的visited数组。然后,在每一轮循环,找到距离源点最近的未加入S集合的顶点u,并将其加入S集合。然后,遍历源点的所有邻居顶点v,更新源点到v的距离。最后返回源点到其他所有顶点的最短距离dist。 运行上述代码,输出结果为:[0, 7, 3, 10, 5],表示源点0到其他各个顶点的最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值