https://www.jianshu.com/p/ff6db00ad866
这篇文章相当清楚。
对代码做了一点小改动,让输出结点名而不是结点下标。
package com.ex.greedy; public class Dijkstra { static final int N=10000; public static void main(String[] args) { int[][] weight1={ {0,4,N,2,N}, {4,0,4,1,N}, {N,4,0,1,3}, {2,1,1,0,7}, {N,N,3,7,0} }; char[] nodes1={'A','B','C','D','E'}; int start=0; int[] shortDis = dijkstra(weight1, nodes1, start); for (int i = 0; i < shortDis.length; i++) { System.out.println("从"+nodes1[start]+"出发到"+nodes1[i]+"的最短路径为:"+shortDis[i]); } } /** * 求起始顶点到各个顶点的最短路径,并输出最短路径经历的顶点 * @param weight 邻接矩阵 * @param nodes 顶点数组 * @param start 起始顶点的下标 * @return 返回起始顶点到各个顶点的最短路径距离 */ public static int[] dijkstra(int[][] weight, char[] nodes, int start) { //1.准备 int n=nodes.length;//顶点个数 int[] shortDis=new int[n];//记录S集合中从start到其余顶点的最短路径距离 int[] visited=new int[n];//记录这个顶点的最短路径有没有求出来,1是已求出 String path[]=new String[n];//记录start到其他各点最短路径的字符串表示 for (int i = 0; i < n; i++) { path[i]=nodes[start]+"—>"+nodes[i]; } //2.初始化 visited[start]=1; // shortDis[start]=0; //3.循环 for (int k = 1; k < n; k++) {//要加入除起始结点外的剩下n-1个顶点 //3.1选择新结点 int min=N,index=-1; for (int i = 0; i < n; i++) { if (visited[i]==0 && weight[start][i]<min){//选出一个距离初始顶点start最近的未标记顶点 min=weight[start][i]; index=i; } } //3.2将新结点加入集合 visited[index]=1; shortDis[index]=min; //3.3更新 for (int i = 0; i < n; i++) { //对集合U中的数据进行更新:如果‘start到中间结点index的距离’+‘index到当前顶点的距离’<‘目前start到当前顶点的最短距离’,就更新 if (visited[i]==0 && weight[start][index]+weight[index][i]<weight[start][i]){ weight[start][i]=weight[start][index]+weight[index][i]; path[i]=path[index]+"—>"+nodes[i]; } } } //输出路径 for (int i = 0; i < n; i++) { System.out.println("从"+nodes[start]+"出发到"+nodes[i]+"的最短路径为:"+path[i]); } System.out.println("=================="); //返回结果 return shortDis; } }
每次选择新顶点后,将新顶点加入集合S:置访问标记为1,将最短路径赋值到shortDis。
U集合中记录的最短距离实际是邻接矩阵中起始顶点那一行的数据。
每次选择新顶点后,对集合U中的数据进行更新:更新邻接矩阵中的最短路径距离和最短路径字符串。
浙公网安备 33010602011771号