迪杰斯特拉算法:从出发顶点到其他顶点的最短路径。
基于已经求出的最短路径,求出更远顶点的最短路径,用dis[j]表示从出发顶点到顶点j的距离,weight[k][j]表示从顶点k到顶点j的距离,那么即dis[j] = min{dis[j], dis[k] + weight[k][j]}。
public class Dijkstra {
public static void main(String[] args) {
Dijkstra d = new Dijkstra();
//顶点之间的连接情况,65535表示不连通
int[][] weight = new int[][]{
{65535, 5, 7, 65535, 65535, 65535, 2},
{5, 65535, 65535, 9, 65535, 65535, 3},
{7, 65535, 65535, 65535, 8, 65535, 65535},
{65535, 9, 65535, 65535, 65535, 4, 65535},
{65535, 65535, 8, 65535, 65535, 5, 4},
{65535, 65535, 65535, 4, 5, 65535, 6},
{2, 3, 65535, 65535, 4, 6, 65535}};
int len = weight.length;
int[] alreadyArr = new int[len]; //标记顶点是否被访问过
int[] dis = new int[len]; //出发顶点到所有顶点的距离(可以经过其他结点),最终存储的就是最短距离
int index = 1;
alreadyArr[index] = 1;
for (int i = 0; i < len; i++){
dis[i] = weight[index][i];
}
dis[index] = 0;
for (int i = 1; i < len; i++){
index = d.selectNode(dis, alreadyArr);
d.updateDis(dis,alreadyArr,weight,index);
}
System.out.println(Arrays.toString(dis));
}
//选择新的访问结点:没被访问过的且到出发结点距离最短(即dis[i]最小)的结点
public int selectNode(int[] dis, int[] alreadyArr){
int min = 65535;
int index = -1;
for (int i = 0; i < dis.length; i++){
if (alreadyArr[i] == 0 && dis[i] < min){
min = dis[i];
index = i;
}
}
alreadyArr[index] = 1;
return index;
}
//更新距离,如果出发结点到index结点(中间可能还经过其他结点,最终的距离就是dis[index])再到i结点(weight[index][i])
//的距离之和(记为len)小于出发结点直接到i结点的距离,且i结点没被访问过(避免重复),就更新dis(i)=len,
public void updateDis(int[] dis, int[] alreadyArr, int[][] weight, int index){
for (int i = 0; i < dis.length; i++){
int len = dis[index] + weight[index][i];
if (alreadyArr[i] == 0 && len < dis[i]){
dis[i] = len;
}
}
}
}