news 2026/9/9 13:50:31

最短路径-Dijkstra

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最短路径-Dijkstra

算法设计

解决2个问题

如何存放最短路径长度:

用一维数组dist[j]存储!源点v默认, dist[j]表示源点 中顶点j的最短路径长度。如dist[2]=12表示源点中顶点2的最短路径长度为12。

如何存放最短路径:

从源点到其他顶点的最短路径有n-1条,一条最短路径用一个一维数组表示,如从顶点0中5的最短路径为0、2、3、5.表示为

path[5]={0,2.3,5}.

所有n-1条最短路径可以用二维数组path[]存储。

例:

转为矩阵形式

Path 数组说明

Path 表示:存放最短路径顶点

{−1表示源点 0 到顶点没有路径0从源点 0 的最短路径,且最短路径上顶点的前一个顶点是源点 0,即 path[0]=0

初始状态
  • 距离数组:dist=[0,4,6,6,∞,∞,∞]
    • 路径数组:path=[0,0,0,−1,−1,−1]
计算步骤

1 初始化:S={0},U={1,2,3,4,5,6}

② 在 U中找到最小顶点 1(权重最小),加入 S={0,1,U={2,3,4,5,6}
顶点 1 出发有 2, 4 顶点:

{dis[2]=min⁡{dis[2],dis[1]+1}=min⁡{6,5}=5dis[4]=min⁡{dis[4],dis[1]+7}=min⁡{4+7,6}=11

修改后:

  • dis=[0,4,5,6,11,∞,∞]
    • path=[0,0,1,0,1,−1,−1]

③ 在 U 中找到最小顶点 2(权重最小),加入 S={0,1,2}S={0,1,2},U={3,4,5,6}
顶点 2 出发有 4, 5 顶点:

{dis[4]=min⁡{dis[4],dis[2]+6}=min⁡{11,5+6}=11dis[5]=min⁡{dis[5],dis[2]+4}=min⁡{∞,5+4}=9

修改后:

  • dis=[0,4,5,6,11,9,∞]dis=[0,4,5,6,11,9,∞]
    • path=[0,0,1,0,1,2,−1]path=[0,0,1,0,1,2,−1]

④ 在 U中找到最小顶点 3(权重最小),加入 S={0,1,2,3},U={4,5,6}
顶点 3 出发有 2, 5 顶点:

{dis[2]=min⁡{dis[2],dis[3]+5}=min⁡{5,6+5}=5(无需修改)dis[5]=min⁡{dis[5],dis[3]+5}=min⁡{9,6+5}=9(无需修改)

无修改:

  • dis=[0,4,5,6,11,9,∞]
    • path=[0,0,1,0,1,2,−1]

⑤ 在 U 中找到最小顶点 5(权重最小),加入 S={0,1,2,3,5},U={4,6}

顶点 5 出发有 4, 6 顶点:

{dis[4]=min⁡{dis[4],dis[5]+1}=min⁡{11,9+1}=10dis[6]=min⁡{dis[6],dis[5]+8}=min⁡{∞,9+8}=17

修改后:

  • dis=[0,4,5,6,10,9,17]
    • path=[0,0,1,0,5,2,5]

⑥ 在 U 中找到最小顶点 4(权重最小),加入 S={0,1,2,3,5,4},U={6}
顶点 4 出发有 6 顶点:

dis[6]=min⁡{dis[6],dis[4]+6}=min⁡{17,10+6}=16

修改后:

  • dis=[0,4,5,6,10,9,16]dis=[0,4,5,6,10,9,16]
    • path=[0,0,1,0,5,2,4]path=[0,0,1,0,5,2,4]

⑦ 在 U 中找到最小顶点 6(权重最小),加入 S={0,1,2,3,5,4,6},U={}
顶点 6 出发没有任何顶点 S 包括路径。

最终结果:

  • 最短距离:dis[6]=16dis[6]=16
    • 最短路径:0→1→2→5→4→6

代码(java)

public class DijkstraAlgorithm { private static final int MAXV = 7; private static final int INF = Integer.MAX_VALUE / 2; public static void main(String[] args) { MatGraph g = new MatGraph(MAXV); g.edges = new int[MAXV][MAXV]; // 初始化图 g.edges[0][1] = 4; g.edges[0][2] = 6; g.edges[0][3] = 6; g.edges[0][4] = INF; g.edges[0][5] = INF; g.edges[0][6] = INF; g.edges[1][0] = INF; g.edges[1][1] = 0; g.edges[1][2] = 1; g.edges[1][3] = INF; g.edges[1][4] = 7; g.edges[1][5] = INF; g.edges[1][6] = INF; g.edges[2][0] = INF; g.edges[2][1] = INF; g.edges[2][2] = 0; g.edges[2][3] = INF; g.edges[2][4] = 6; g.edges[2][5] = 4; g.edges[2][6] = INF; g.edges[3][0] = INF; g.edges[3][1] = INF; g.edges[3][2] = 2; g.edges[3][3] = 0; g.edges[3][4] = INF; g.edges[3][5] = 5; g.edges[3][6] = INF; g.edges[4][0] = INF; g.edges[4][1] = INF; g.edges[4][2] = INF; g.edges[4][3] = INF; g.edges[4][4] = 0; g.edges[4][5] = INF; g.edges[4][6] = 6; g.edges[5][0] = INF; g.edges[5][1] = INF; g.edges[5][2] = INF; g.edges[5][3] = INF; g.edges[5][4] = 1; g.edges[5][5] = 0; g.edges[5][6] = 8; g.edges[6][0] = INF; g.edges[6][1] = INF; g.edges[6][2] = INF; g.edges[6][3] = INF; g.edges[6][4] = INF; g.edges[6][5] = INF; g.edges[6][6] = 0; // 对角线元素设为0 for (int i = 0; i < MAXV; i++) { g.edges[i][i] = 0; } // 其他位置设为INF for (int i = 0; i < MAXV; i++) { for (int j = 0; j < MAXV; j++) { if (g.edges[i][j] == 0 && i != j) { g.edges[i][j] = INF; } } } int v = 0; // 源点 int[] dist = new int[MAXV]; int[] path = new int[MAXV]; boolean[] S = new boolean[MAXV]; Dijkstra(g, v, dist, path, S); Dispath(g, dist, path, S, v); } public static void Dijkstra(MatGraph g, int v, int[] dist, int[] path, boolean[] S) { for (int i = 0; i < g.n; i++) { dist[i] = g.edges[v][i]; S[i] = false; if (g.edges[v][i] < INF) { path[i] = v; } else { path[i] = -1; } } S[v] = true; path[v] = 0; for (int i = 0; i < g.n - 1; i++) { int u = findMinDistanceVertex(dist, S); S[u] = true; for (int j = 0; j < g.n; j++) { if (!S[j] && g.edges[u][j] < INF && dist[u] + g.edges[u][j] < dist[j]) { dist[j] = dist[u] + g.edges[u][j]; path[j] = u; } } } } private static int findMinDistanceVertex(int[] dist, boolean[] S) { int minDistance = INF; int minIndex = -1; for (int j = 0; j < dist.length; j++) { if (!S[j] && dist[j] <= minDistance) { minDistance = dist[j]; minIndex = j; } } return minIndex; } public static void Dispath(MatGraph g, int[] dist, int[] path, boolean[] S, int v) { for (int i = 0; i < g.n; i++) { if (S[i] && i != v) { System.out.printf("从顶点%d 到顶点%d 的路径长度为: %d 路径为: ", v, i, dist[i]); printPath(path, v, i); } } } private static void printPath(int[] path, int v, int i) { if (path[i] == -1) { System.out.println("无路径"); return; } int[] apath = new int[MAXV]; int d = 0; apath[d++] = i; int k = path[i]; while (k != v) { apath[d++] = k; k = path[k]; } apath[d++] = v; System.out.print(apath[d - 1]); for (int j = d - 2; j >= 0; j--) { System.out.print(" -> " + apath[j]); } System.out.println(); } static class MatGraph { int n; int[][] edges; public MatGraph(int n) { this.n = n; } } }

结果:

*从顶点0 到顶点1 的路径长度为: 4 路径为: 0 -> 1
* 从顶点0 到顶点2 的路径长度为: 5 路径为: 0 -> 1 -> 2
* 从顶点0 到顶点3 的路径长度为: 6 路径为: 0 -> 3
* 从顶点0 到顶点4 的路径长度为: 10 路径为: 0 -> 1 -> 2 -> 5 -> 4
* 从顶点0 到顶点5 的路径长度为: 9 路径为: 0 -> 1 -> 2 -> 5
* 从顶点0 到顶点6 的路径长度为: 16 路径为: 0 -> 1 -> 2 -> 5 -> 4 -> 6

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 13:50:14

用Hashids隐藏自增ID:C端接口防枚举与防泄露实践

做了几年 C 端后端&#xff0c;有个问题几乎每次评审都会被翻出来——接口里直接返回自增 ID。用户 ID 是 1、2、3&#xff0c;订单号是 10001、10002&#xff0c;看一眼 URL 就知道平台体量有多大&#xff0c;改一下参数就能遍历别人的数据。你跟他讲性能&#xff0c;他说我就…

作者头像 李华
网站建设 2026/9/9 13:49:35

从形式合规到实质安全:企业网络安全合规自查体系落地指南

1. 为什么你家的合规自查&#xff0c;总是“查了个寂寞”做网络安全这些年&#xff0c;我接过不少企业的安全咨询&#xff0c;也帮好几家公司搭过内部的合规自查体系。每次开场沟通&#xff0c;对方都会拿出一堆材料&#xff1a;各种制度文档、培训记录、漏洞扫描报告、渗透测试…

作者头像 李华
网站建设 2026/9/9 13:45:19

Python量化交易学习指南:从环境搭建到双均线策略回测

简介&#xff1a;这是一份面向量化交易入门者的Python学习代码示例集&#xff0c;聚焦股票、ETF与概念板块的数据处理及策略分析场景&#xff0c;适合希望用Python将金融数据转化为可执行策略的初学者参考。资源共253个文件&#xff0c;以106个py脚本为核心&#xff0c;配套132…

作者头像 李华
网站建设 2026/9/9 13:37:04

从ECC原理到MBIST自检:服务器内存报错排查指南

开机自检卡在POST界面&#xff0c;屏幕上孤零零地挂着一行“uncorr. ECC 显示2”&#xff0c;系统怎么也不肯进系统。如果你运维过服务器&#xff0c;大概率对这个画面不陌生。我见过不少同事第一反应就是“内存坏了&#xff0c;赶紧换”&#xff0c;结果换了三四根还是报错&am…

作者头像 李华
网站建设 2026/9/9 13:37:03

STM32嵌入式Web服务器开发实战:从LwIP到HTTP协议实现

简介&#xff1a;STM32实现Web服务器是面向嵌入式开发者和物联网初学者的实战资料&#xff0c;以STM32微控制器与轻量级LwIP协议栈为核心&#xff0c;完整演示在资源受限的MCU上完成以太网接入、TCP/IP通信搭建&#xff0c;并对外提供HTTP服务&#xff0c;解决单片机联网难、We…

作者头像 李华
网站建设 2026/9/9 13:36:49

STM32F103输入捕获测量PWM占空比与周期详解

简介&#xff1a;STM32F103输入捕获工程资源&#xff0c;面向需要测量外部PWM信号周期与占空比的嵌入式开发者与学习者&#xff0c;提供一套基于Keil5的完整工程示例。资源围绕定时器输入捕获原理展开&#xff0c;从定时器初始化、输入捕获通道配置到中断服务程序编写&#xff…

作者头像 李华