用到的测试图
package algorithm;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
/**
*迪杰斯特拉算法
*/
public class Dij {
private int vertexNum;
private int[][] martix;
private boolean[] S;//已经求得的最短路径的顶点
private boolean[] U;//未求的最短路径的顶点
private Map<Integer,Integer> dist = new HashMap<>();//保存最短路径key代表终点 value代表当前的最短路径
private int currentMidVertex;//当前的中间点,也就是每次产生的最短路径的那个点,该点之前不再S集合中
private int startVertex = 0;
public Dij(int[][] martix,int vertexNum) {
this.martix = martix;
this.vertexNum = vertexNum;
S = new boolean[vertexNum];
U = new boolean[vertexNum];
}
private void init(int startVertex) {
//初始化S和U集合
S[startVertex] = true;
U[startVertex] = false;
for(int i = 0; i<vertexNum; i++) {
if(i!=startVertex)
U[i] = true;
}
//初始化dist集合
for(int i = 0;i<vertexNum;i++) {
if(i!=startVertex) {
if(martix[startVertex][i]!=0) {
dist.put(i, martix[startVertex][i]);
} else {
dist.put(i, Integer.MAX_VALUE);
}
}
}
//初始化中间点
this.currentMidVertex = startVertex;
}
public void dij(int startVertex) {//从哪个顶点出发
this.startVertex = startVertex;
init(startVertex);
for(int i = 1;i<vertexNum;i++) {//循环顶点个数-1那么多次,每次加入一个顶点到S集合中
currentMidVertex = shorestPath();//找到dist中当前最短路径的终点是哪一个
if(currentMidVertex==Integer.MAX_VALUE) {
continue;
}
S[currentMidVertex] = true;
U[currentMidVertex] = false;
//更新dist,使得其他路径经过currentMidVertex,如果路径值更小那么更新
Set<Entry<Integer, Integer>> set = dist.entrySet();
for (Entry<Integer, Integer> entry : set) {
if(entry.getKey()!=currentMidVertex) {
int newPath = dist.get(currentMidVertex);
int b = path(currentMidVertex,entry.getKey());
if(b!=0) {
newPath+=b;
} else {//没有可走的路径从currentMidVertex到终点
continue;
}
if(newPath < entry.getValue()) {//如果更小就更新
dist.put(entry.getKey(), newPath);
}
}
}
}
}
public void output() {
Set<Entry<Integer, Integer>> set = dist.entrySet();
for (Entry<Integer, Integer> entry : set) {
if(entry.getValue() == Integer.MAX_VALUE) {
System.out.println(startVertex+"->"+entry.getKey()+"的最短路径长度为:没有路径");
continue;
}
System.out.println(startVertex+"->"+entry.getKey()+"的最短路径长度为:"+entry.getValue());
}
}
private Integer path(int start, Integer destination) {//寻找一个路径起点是start,终点是destination
if(martix[start][destination]!=0) {
return martix[start][destination];
}
return 0;
}
//遍历dist返回当前的最短路径的终点是哪个
public int shorestPath() {
Set<Entry<Integer, Integer>> set = dist.entrySet();
int minKey = Integer.MAX_VALUE;
int minPath = Integer.MAX_VALUE;
for (Entry<Integer, Integer> entry : set) {
if(U[entry.getKey()]) {
int key = entry.getKey();
int value = entry.getValue();
if(value < minPath) {
minPath = value;
minKey = key;
}
}
}
return minKey;
}
public static void main(String[] args) throws Exception {
System.setIn(new FileInputStream("C:\\Users\\colin\\Desktop\\data2.txt"));
Scanner scanner = new Scanner(System.in);
//System.out.println("输入顶点个数:");
int n = scanner.nextInt();
//System.out.println("输入边的个数:");
int m = scanner.nextInt();
int[][] martix = new int[n][n];
//System.out.println("输入每条边,每一行包含3个数,a,b,c:代表起点,终点,和权值");
for(int i= 0;i<m;i++) {
int a = scanner.nextInt();
int b = scanner.nextInt();
int c = scanner.nextInt();
martix[a][b] = c;
}
Dij dij = new Dij(martix, n);
dij.dij(1);
dij.output();
}
}
测试结果:
v1为起点
1->2的最短路径长度为:没有路径
1->3的最短路径长度为:10
1->4的最短路径长度为:50
1->5的最短路径长度为:30
1->6的最短路径长度为:60
v2为起点:
2->1的最短路径长度为:没有路径
2->3的最短路径长度为:5
2->4的最短路径长度为:55
2->5的最短路径长度为:没有路径
2->6的最短路径长度为:65
依次类推,可以任意选择起点求最短路径