问题描述
给定带权有向图 G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在计算从源到所有其他各顶点的最短长度。这里的长度指路上各边权之和。
算法设计
给定带权有向图 G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在计算从源到所有其他各顶点的最短长度。这里的长度指路上各边权之和。
数据结构选择
带权邻接矩阵a记录结点之间的权值, 数组dist来记录从源点到其它顶点的最短路径长度, 数组pre来记录最短路径;
结果展示
代码实现
package test;
public class Test2 {
/**
* Dijkstra 算法
* @param v 源
* @param a 记录节点之间的权重
* @param dist 源点到其他顶点之间的最短路径长度
* @param prev 记录最短路径
*/
public static void dijkstra(int v,float[][] a,float[] dist,int[] prev){
int n = dist.length-1;
boolean[] s = new boolean[n+1];
//初始化
for(int i = 1;i <= n;i++){
dist[i] = a[v][i];
s[i] = false;
if(dist[i] == Float.MAX_VALUE)
prev[i] = 0;
else
prev[i] = v;
}
//源点路径为0
dist[v] = 0;
s[v] = true;
for(int i = 1;i < n;i++){
float temp = Float.MAX_VALUE;
int u = v;
for(int j = 1;j <= n;j++){
if((!s[j])&&(dist[j]<temp)){
u = j;
temp = dist[j];
}
}
//找出次小的节点
s[u]=true;
for(int j = 1;j <= n;j++)
if((!s[j])&&(a[u][j]<Float.MAX_VALUE)){
float newdist = dist[u]+a[u][j];
if(newdist<dist[j]){
dist[j]=newdist;
prev[j]=u;
}
}
}
}
public static void main(String[] args) {
float[][]a = new float[6][6];
for(int i = 1;i<6;i++ )
for(int j = 1;j<6;j++)
a[i][j] = Float.MAX_VALUE;
a[1][2] = 10;
a[1][4] = 30;
a[1][5] = 100;
a[2][3] = 50;
a[3][5] = 10;
a[4][3] = 20;
a[4][5] = 60;
a[1][1] = 0;
a[2][2] = 0;
a[3][3] = 0;
a[4][4] = 0;
a[5][5] = 0;
float[] dist = new float[6];
int[] prev = new int[6];
int v = 1;
dijkstra(v,a,dist,prev);
System.out.println("该图的邻接矩阵为:");
for(int i = 1;i<6;i++ ){
for(int j = 1;j<6;j++){
System.out.print(a[i][j]+" ");
}
System.out.println();
}
System.out.println("最短路径长度:");
for(int i = 1;i<6;i++)
System.out.print(dist[i]+" ");
System.out.println();
System.out.println("最短路径为:");
for(int i = 1;i<6;i++)
System.out.print(prev[i]+" ");
}
}