!!!!又稱銀行家算法,超經典超難的!!!!
迪傑斯特拉是找一個結點到其它所有結點的最短路徑 用文字描述有點難
一開始目標結點只能到達臨近的點
此時選擇路徑最小的點
更新目標點到其它點的距離(因爲可以經過最小的點到達其它點)
在新的距離中繼續找最小點
package Algorithm;
import java.util.Arrays;
public class Dijkstra {
public static void main(String[] args) {
// TODO Auto-generated method stub
char[] vertexs = {'A','B','C','D','E','F','G'};
int[][] martex = new int[vertexs.length][vertexs.length];
final int N = 65535;
martex[0] = new int[] {N,5,7,N,N,N,2};
martex[1] = new int[] {5,N,N,9,N,N,3};
martex[2] = new int[] {7,N,N,N,8,N,N};
martex[3] = new int[] {N,9,N,N,N,4,N};
martex[4] = new int[] {N,N,8,N,N,5,4};
martex[5] = new int[] {N,N,N,4,5,N,6};
martex[6] = new int[] {2,3,N,N,4,6,N};
Graph graph = new Graph(vertexs,martex);
graph.showGraph();
graph.dsj(6);
graph.showDijkstra();
}
static class VisitedVertex{
//記錄各個頂點是否被訪問 1表示訪問0 表示未訪問
public int[] already_array;
//給個下標對應的值爲前一個原點下標,會動態更新
public int[] pre_visited;
//記錄出發頂點到其它所有頂點的距離
public int[] dis;
public VisitedVertex(int length,int index) {
this.already_array = new int[length];
//index表示出發頂點對應的下標
this.pre_visited = new int[length];
this.dis = new int[length];
//初始化dis
Arrays.fill(dis, 65535);
this.already_array[index] = 1; //設置出發頂點被訪問過
this.dis[index] = 0;
}
//判斷Index是否被訪問古過 如果訪問過返回true
public boolean in(int index) {
return already_array[index] == 1;
}
public void updateDis(int index,int len) {
//更新出髮結點到index結點的距離
dis[index] = len;
}
//更新結點Pre的前驅結點爲index
public void updatePre(int pre,int index) {
pre_visited[pre] = index;
}
public void show() {
//輸出數組
System.out.println(Arrays.toString(already_array));
System.out.println(Arrays.toString(pre_visited));
System.out.println(Arrays.toString(dis));
}
//返回出發結點到index結點的距離
public int getDis(int index) {
return dis[index];
}
public int updateArr() {
int min = 65535,index = 0;
for(int i = 0; i < already_array.length; i++) {
if(already_array[i] == 0 && dis[i] < min) {
min = dis[i];
index = i;
}
}
already_array[index] = 1;
return index;
}
}
static class Graph{
private char[] vertex;
private int[][] matrix;
private VisitedVertex vv;//已經訪問的頂點的集合
//構造器
public void dsj(int index) {
//重點注意這一句 我寫的VisitedVertex vv = new VisitedVertex(vertex.length,index);然後報錯 是因爲此時的vv被重新創建必然爲null
vv = new VisitedVertex(vertex.length,index);
update(index);
for(int i = 1; i < vertex.length; i++) {
index = vv.updateArr();
update(index);
}
}
//更新Index下標
private void update(int index) {
int len = 0;
//根據遍歷鄰接矩陣的 matrix[index]
for(int i = 0; i < matrix[index].length;i++) {
//出發結點到index的距離+index到結點i的距離
len = vv.getDis(index) + matrix[i][index];
//如果i結點沒有訪問過並且Len要小於出發點到I的距離,則將距離替換爲vv,將index的前驅爲i
if(!vv.in(i) && len < vv.getDis(i)) {
vv.updatePre(i, index);
vv.updateDis(i, len);
}
}
}
public Graph(char[] vertex, int[][] matrix) {
super();
this.vertex = vertex;
this.matrix = matrix;
}
//顯示圖
public void showGraph() {
for(int[] link : matrix) {
System.out.println(Arrays.toString(link));
}
}
public void showDijkstra() {
vv.show();
}
}
}