求点A到点E的最短距离
package com.byc.day2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DijkstraAlgorithm {
public static void main(String[] args) {
//1、所有的顶点
char[] vertex = {'A','B','C','D','E','F','G'};
// 2、邻接矩阵
int[][] matrix = new int[vertex.length][vertex.length];
final int N = 65535;// 表示不可连接
matrix[0] = new int[]{N,5,7,N,N,N,2};
matrix[1] = new int[]{5,N,N,9,N,N,3};
matrix[2] = new int[]{7,N,N,N,8,N,N};
matrix[3] = new int[]{N,9,N,N,N,4,N};
matrix[4] = new int[]{N,N,8,N,N,5,4};
matrix[5] = new int[]{N,N,N,4,5,N,6};
matrix[6] = new int[]{2,3,N,N,4,6,N};
// 3、创建 Graph 对象
Graph graph = new Graph(vertex, matrix);
// 4、测试,看看图的邻接矩阵是否ok
graph.showGraph();
// 5、计算出所有顶点到 0 的最短距离和前驱结点
graph.dsj(graph.vertexList.indexOf('A'));
// 6、获得 0 -> 5 号结点的最短距离
int dis = graph.vv.getDis(graph.vertexList.indexOf('E'));
System.out.println(dis);
// 7、打印最短路径从 0 -> 5 的经过的所有的点
graph.printVisit(graph.vertexList.indexOf('E'));
}
}
class Graph{
private char[] vertex; //顶点数组
private int[][] matrix; //邻接矩阵
public VisitedVertx vv;
public List<Character> vertexList;
private final int N = 65535;
// 构造器
public Graph(char[] vertex, int[][] matrix) {
this.vertex = vertex;
this.matrix = matrix;
vertexList = getList(vertex);
}
// 显示图
public void showGraph(){
for (int[] link : matrix) {
System.out.println(Arrays.toString(link));
}
}
// 迪杰斯特拉算法的实现
public void dsj(int startIndex){
vv = new VisitedVertx(vertex.length, startIndex);
int[] alreadyArr = vv.alreadyArr;
int now = startIndex;
while (true){
int[] nowCanArrive = this.matrix[now];
for (int i = 0; i < nowCanArrive.length; i++) {
if (alreadyArr[i]==1){
continue;
}
int newDis = vv.getDis(now) + nowCanArrive[i];
if (vv.getDis(i)==N && nowCanArrive[i]!=N) {
vv.updateDis(i,newDis);
vv.updatePre(i,now);
} else if (vv.getDis(i)!=N && nowCanArrive[i]!=N){
if (newDis < vv.getDis(i)) {
vv.updateDis(i,newDis);
vv.updatePre(i,now);
}
}
}
int minIndex = -1;
int minDis = N;
for (int i1 = 0; i1 < alreadyArr.length; i1++) {
if (alreadyArr[i1]==1){
continue;
}
int dis = vv.getDis(i1);
if (dis < minDis){
minIndex = i1;
minDis = dis;
}
}
if (minIndex == -1){
break;
}
alreadyArr[minIndex] = 1;
now = minIndex;
}
System.out.println();
}
public void printVisit(int index){
if (vv.preVisited[index]==index){
System.out.print(vertexList.get(index) + "\t");
} else {
printVisit(vv.preVisited[index]);
System.out.print(vertexList.get(index) + "\t");
}
}
private static List<Character> getList(char[] vertex) {
List<Character> characters = new ArrayList<>();
for (char c : vertex) {
characters.add(c);
}
return characters;
}
}
// 已访问顶点的集合
class VisitedVertx{
// 记录各个顶点是否访问过 1表示已经ok,0会动态更新
public int[] alreadyArr;
// 每个下标对应的值为第一个顶点的下标,会动态更新
public int[] preVisited;
// 记录出发顶点到其他所有点的距离,例如G为出发点,就会记录G到其他顶点的距离,会动态更新,求的最短距离就会存放到dis
public int[] dis;
public VisitedVertx(int length, int index) {
this.alreadyArr = new int[length];
this.preVisited = new int[length];
this.dis = new int[length];
//初始化dis数组
Arrays.fill(dis,65535);
this.dis[index] = 0;
this.preVisited[index] = index;
this.alreadyArr[index] = 1;
}
/**
* 判断该顶点是否被访问过
* 如果被访问过,就返回true,否则返回false
*/
public boolean in(int index){
return alreadyArr[index] == 1;
}
/**
* 更新从出发点到顶点index的距离
*/
public void updateDis(int index, int len){
dis[index] = len;
}
/**
* 更新顶点为前驱index顶点
*/
public void updatePre(int pre,int index){
preVisited[pre] = index;
}
/**
* 功能:返回出发点到index点的距离
*/
public int getDis(int index){
return dis[index];
}
}