Dijkstra算法可以说基本上每一本有讲到图的最短路径的书上都会有的一个算法,但基本上都是讲原理和伪代码,今天自己用Java代码给实现了一下,记录在此。
Dijkstra算法只是解决某些图的最短路径问题,这些图需要满足以下条件:权值非负、有向图。并且该算法只适用于求单源点最短路径,即起始点只是固定的某一个点,当然了,如果想求多源点最短路径,多用几次Dijkstra算法也是能求出来的。
该算法的原理就是:先处理源点,更新一下从源点到每个点的距离以及前结点信息,完后源点放到“已处理”组,从“未处理”组再找一个距离起点最近的点,看下是否有些点的路径在经过这个点后比原来的路径更短了,如果是,那么更新下距离以及前结点信息,如果否,不作操作,完后此点也放入“已处理”组,循环直到所有点都处理完。下面上代码:(最终打印路径的时候偷懒了一下没有把路径倒过来打印)
package classic;
import java.util.Scanner;
public class Dijkstra {
public static int start = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("输入点和边的数目:");
int V = sc.nextInt();//总共有多少个点
int E = sc.nextInt();//总共有多少个边
int[][] G = new int[V][V];//用来存放图的信息
int[] d = new int[V];//用来存放从起点到每个点的最短路径长度
int[] pre = new int[V];//用来存放每个点在其最短路径上的前一个结点
boolean[] used = new boolean[V];
System.out.println("依次输入每条边的起点、终点和权值:(点的编号从0开始)");
for(int i=0; i<E; i++){
G[sc.nextInt()][sc.nextInt()] = sc.nextInt();
}
for(int i=0; i<V; i++){//初始化d
pre[i] = start;
if(i==start){
d[i] = 0;
continue;
}
if(G[start][i]==0)
d[i] = Integer.MAX_VALUE/E;
else{
d[i] = G[start][i];
}
}
int cur = 0;
used[start] = true;
while(cur<V){
int minDis = Integer.MAX_VALUE/E;
int minIndex = 0;
for(int i=0; i<V; i++){//每次取d[i]最小的那个点
if(!used[i] && d[i]<minDis){
minDis = d[i];
minIndex = i;
}
}
used[minIndex] = true;
for(int i=0; i<V; i++){
if(G[minIndex][i]>0 && d[i]>d[minIndex]+G[minIndex][i]){
d[i] = d[minIndex]+G[minIndex][i];
pre[i] = minIndex;
}
}
cur++;
}
for(int i=0; i<V; i++){
System.out.println("起点"+start+"到点"+i+"的最短路径长度为:"+d[i]);
System.out.println("最短路径为:");
int curv = i;
System.out.print(i+"<-");
while(true){
curv = pre[curv];
if(curv == start)
break;
System.out.print(curv+"<-");
}
System.out.println(start);
}
sc.close();
}
}