网上很多案例都是用的C++写的,但是我一般写Java多些,通过学习算法的基本理论,在Java上实现一遍。
public class DIJKSTRA {
private static long[][] map = new long[1000][1000];
private static long INF = (long) 1e9;
private static long[] dis = new long[1000];
private static int n,m;
private static int x,y,r;
private static int i_temp;
private static int ini,obj;
private static List<Integer> list = new ArrayList<>();
public DIJKSTRA() {
}
//初始值的设定,包括节点数量,边数,起始出发点,终点
public void init(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入节点数、边数、起始点、终点(n、m、ini、obj):");
n = sc.nextInt();m = sc.nextInt();ini = sc.nextInt();obj = sc.nextInt();
//把路径集合的第一个点设为初始点
list.add(ini);
int m_temp = m;//为了后边输出,找了个临时变量来记录一下,不是重点!
//把流量矩阵初始化!对角线为0,其他全是无穷大
for (int i = 1; i <= n ; i++) {
for (int j = 1; j <= n ; j++) {
if(i == j){
map[i][j] = 0;
}else {
map[i][j] = INF;
}
}
}
//路径要素初始化,r是两点之间的距离,并且导入到map流量矩阵中
while (m > 0){
System.out.println("请输入第"+ (m_temp + 1 - m) +"条边的信息(x,y,r):");
x = sc.nextInt();y = sc.nextInt();r = sc.nextInt();
map[x][y] = r;
m--;
}
//初始化最短路径
for (int i = 1; i <= n ; i++) {
dis[i] = map[ini][i];
}
}
public void Dijkstra(){
int[] vis = new int[n + 1];
vis[ini] = 1;
int n_temp = n - 1;
while (n_temp > 0) {
long min = INF;
n_temp--;
//找出尚未确定最短路径的节点并且在下一次扫描路径最短的点
for (int i = 1; i <= n; i++) {
if(dis[i] < min && vis[i] == 0){
min = dis[i];
}
}
//锁定节点目标
for (int i = 1; i <= n; i++) {
if(min == dis[i] && vis[i] == 0){
vis[i] = 1;
i_temp = i;
//如果obj还没走完,那么把这个节点加入当中
if(vis[obj] == 0 ){
list.add(i);
}
break;
}
}
//基于新确定的节点,对其他还没有确定最短路径的节点,开始更新新的路径数据
for (int i = 1; i <= n; i++) {
if(vis[i] == 0 && map[i_temp][i] < INF / 2 && dis[i] > dis[i_temp] + map[i_temp][i]){
dis[i] = dis[i_temp] + map[i_temp][i];
}
}
}
//最后把obj作为目的节点的最后一站
list.add(obj);
}
//输出得到的结果
public void out(){
for (int i = 1; i <= n; i++) {
System.out.println("从"+ ini +"--"+ i +"的最短路径为:" + dis[i]);
}
System.out.println("从"+ini+"到达"+obj+"的最短路径需要依次经过:"+list);
}
}
算法的原理如下: