Dijkstra算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先),直到扩展到终点为止。算法过程太麻烦不写了,直接上代码理解。
import java.util.Arrays;
public class DijkstraAlgorithm {
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] verxs = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
final int INF = 65535;
int matrix[][] = { { 0, 12, INF, INF, INF, 16, 14 }, { 12, 0, 10, INF, INF, 7, INF },
{ INF, 10, 0, 3, 5, 6, INF }, { INF, INF, 3, 0, 4, INF, INF }, { INF, INF, 5, 4, 0, 2, 8 },
{ 16, 7, 6, INF, 2, 0, 9 }, { 14, INF, INF, INF, 8, 9, 0 } };
Graph graph = new Graph(verxs, matrix);
graph.dsj(6);
graph.showDijkstra();
}
}
class Graph {
private char[] verxs;// 顶点数组
private int[][] matrix;// 邻接矩阵
private VisitedVerxs vv;
public Graph(char[] verxs, int[][] matrix) {
this.verxs = verxs;
this.matrix = matrix;
}
public void showDijkstra() {
vv.show();
}
public void showGraph() {
for (int[] link : matrix) {
System.out.println(Arrays.toString(link));
}
}
public void dsj(int index) {
vv = new VisitedVerxs(verxs.length, index);
update(index);// 更新index顶点到周围顶点的距离和前驱顶点
for (int j = 0; j < verxs.length; j++) {
index = vv.updateArr();// 选择并返回新的访问顶点
update(index);
}
}
// 更新index下标顶点到周围顶点的距离和周围顶点的前驱顶点
public void update(int index) {
int len = 0;
for (int j = 0; j < matrix[index].length; j++) {
len = vv.getDis(index) + matrix[index][j];// len是出发顶点到index顶点的距离+从index到j顶点的距离的和
if (!vv.in(j) && len < vv.getDis(j)) {// j没有被访问过,且len小于出发顶点到j顶点的距离
vv.updatePre(j, index);// 更新j顶点的前驱为index顶点
vv.updateDis(j, len);// 更新出发顶点到j顶点的距离
}
}
}
}
class VisitedVerxs {
// 记录各个顶点是否访问过1表示访问过,0表示未访问
public int[] already_arr;
// 每个下标对应的值为前一个顶点下标
public int[] pre_visited;
// 记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其他顶点的距离,秋的最短距离存放到dis
public int[] dis;
public VisitedVerxs(int length, int index) {
this.already_arr = new int[length];// length为顶点个数
this.pre_visited = new int[length];
this.dis = new int[length];
// 初始化dis
Arrays.fill(dis, 65535);
this.already_arr[index] = 1;// 设置出发顶点被访问过
this.dis[index] = 0;// index为出发顶点对应下标,设置出发顶点的访问距离为0
}
// 判断index是否被访问过,访问过为true
public boolean in(int index) {
return already_arr[index] == 1;
}
// 更新出发顶点到index顶点的距离
public void updateDis(int index, int len) {
dis[index] = len;
}
// 更新顶点前驱为index节点
public void updatePre(int pre, int index) {
pre_visited[pre] = index;
}
// 返回出发顶点到index顶点的距离
public int getDis(int index) {
return dis[index];
}
// 继续选择并返回新的访问顶点,比如G完后,就是A作为新的访问顶点
public int updateArr() {
int min = 65535, index = 0;
for (int i = 0; i < already_arr.length; i++) {
if (already_arr[i] == 0 && dis[i] < min) {
min = dis[i];
index = i;
}
}
// 更新index被放问过
already_arr[index] = 1;
return index;
}
// 显示最后的结果,将三个数组的情况输出
public void show() {
for (int i : already_arr) {
System.out.print(i + " ");
}
System.out.println();
for (int i : pre_visited) {
System.out.print(i + " ");
}
System.out.println();
for (int i : dis) {
System.out.print(i + " ");
}
System.out.println();
}
}