Dijkstra算法练习

/**
 * Dijkstra算法思想:
 * 按各顶点与源点start间路径长度的递增次序,生成到各顶点的最短路径的算法。
 * 即求出长度最短的一条最短路径,再参照它求出长度次短的一条路径,以此类推,直到
 * 从源点start到其他各顶点的最短路径全部求出为止。
 * 1.选出一个距离初始顶点start最近的未访问顶点
 * 2.以这个顶点为中间点更新从start到未访问各店的距离
 * */
public class Dijkstra {
public static final int M = 1000000;
public static void main(String[] args) {
//权值矩阵
int[][] weight = {  
       {0,3,2000,7,M}, 
       {3,0,4,2,M}, 
       {M,4,0,5,4}, 
       {7,2,5,0,6},   
       {M,M,4,6,0} 
};
//源点start
int start = 0;
//源点start~i顶点的最短路径所花费的最小代价0 3 7 5 11
int[] shortPathWeight = dijkstra(weight , start);
int length = shortPathWeight.length;
System.out.println("源点start到各顶点最短路径所花费的最小代价");
for(int i = 0 ; i < length ; i++){
if(i == length - 1){
System.out.println(shortPathWeight[i]);
}else{
System.out.print(shortPathWeight[i] + " ");
}
}
}
private static int[] dijkstra(int[][] weight, int start) {
int n = weight.length;//顶点个数
int[] shortPathWeight = new int[n];
String[] shortPath = new String[n];//保存源点start到顶点i最短路径中经过的顶点序列
for(int i = 0 ; i < n ; i++){
shortPath[i] = start + "--->" + i;
}
int[] visit = new int[n];//顶点访问标记
//数据初始化
shortPathWeight[start] = 0;
visit[start] = 1;//起始顶点标记为访问过
//需要循环n-1次找到源点到其余顶点的最短路径长度
for(int count = 1 ; count < n ; count++){
//选出一个距离源点start最近的顶点
int minIndex = -1;
int minWeight = Integer.MAX_VALUE;
//i从0遍历所有顶点,start可以任意取
for(int i = 0 ; i < n ; i++){
if(visit[i] == 0 && weight[start][i] < minWeight){
minWeight = weight[start][i];
minIndex = i;
}
}
//每次找到一个距离源点start最近的顶点,更新其值
shortPathWeight[minIndex] = minWeight;
visit[minIndex] = 1;
//以minIndex顶点为中间点更新从start到未访问各顶点的距离
for(int i = 0 ; i < n ; i++){
//M不能取Integer.MAX_VALUE,防止两个值相加越界变成负数
if(visit[i] == 0 && weight[start][minIndex] + weight[minIndex][i] < weight[start][i]){
weight[start][i] = weight[start][minIndex] + weight[minIndex][i];
//如果两条路径的经过顶点代价一样,则取先找到的那条路径
shortPath[i] = shortPath[minIndex] + "--->" + i;
}
}
}
//打印源点start到顶点i最短路径中经过的顶点序列
System.out.println("源点start分别到各顶点最短路径中经过的顶点序列");
for(int i = 0 ; i < n ; i++){
System.out.println(shortPath[i]);
}
return shortPathWeight;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值