对Dijkstra的思考
迪杰斯特拉算法是一个非常典型的求单源最短路径的算法
/**
* matrix 为邻接矩阵
* node 为单源点
* dist为单源点到各点的最短路径长度
* path 记录最短路径
*/
public class Dijkstra {
public static final int INF = Integer.MAX_VALUE;
public void dijkstra(int[][] matrix, int node, int[] dist, int [] path) {
int n = matrix.length;
//标记已访问的节点,即确定已确定最短路径的集合
boolean[] visited = new boolean[n];
//初始化
for (int i = 0; i < n; i++) {
visited[i] = false;
dist[i] = matrix[node][i];
}
//对node本身初始化
visited[node] = true;
dist[node] = 0;
//源点不存在前驱节点,设为-1
path[node] = -1;
//对每个点进行计算最短路径,共 n-1 次
//记录每次最小路径的位置
int k = 0;
for (int i = 1; i < n; i++) {
int min = INF;
//寻找最短路径
for (int j = 0;j < n; j++){
if (!visited[j] && dist[j] < min){
min = dist[j];
k = j;
}
}
//将当前选中的点加入已选集合
//此处会确定一个点已达到最短路径,可在此处根据题目条件进行具体操作
visited[k] = true;
//更新路径dist
for (int j = 0;j < n;j++){
int len = matrix[k][j] == INF ? INF : min + matrix[k][j];
if (!visited[j] && len < dist[j]){
dist[j] = len;
//已加入节点后,其他为加入的节点的前驱节点为当前节点,以便回溯路径
//若题目有和路径相关的问题,可以在更新path处操作
path[j] = k;
}
}
}
}
@Test
public void test(){
int [][] matrix = {{0,10,INF,INF,5},{INF,0,1,INF,2},{INF,INF,0,4,INF},{7,INF,6,0,INF},{INF,3,9,2,0}};
int node = 0;
int [] dist = new int[matrix.length];
int [] path = new int[matrix.length];
dijkstra(matrix,node,dist,path);
System.out.println("dist:"+Arrays.toString(dist));
System.out.println("path:"+Arrays.toString(path));
}
//输出结果:
//dist:[0, 8, 9, 7, 5]
//path:[-1, 4, 1, 4, 0]
//结果含义: 例如 节点0 到节点 2 的最短路径为 dist[2] = 9,其路径为:0->4->1->2,参考下图