最短路徑在數據結構的教材上有兩種生成算法:Floyed算法和Dijkstra算法node
Floyed算法算法
算法思想:數據結構
經過三個for循環,求出各個點距離其餘各個點的最短距離。其中,最外層for循環遍歷中間節點k,第二第三層循環起點i,終點j;算法思想:若是i節點到k節點的距離 加上 k節點到j節點的距離,那麼i節點到j節點的距離就更新爲dis[i][k] + dis[k][j],等遍歷完全部中間節點,就獲得了全局的最短路徑。ide
public void floyed() { for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (data[i][j] > data[i][k] + data[k][j]) { data[i][j] = data[i][k] + data[k][j]; } } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { System.out.println(String.format("%d->%d:%d", i, j, data[i][j])); } } }
Dijkstra算法spa
算法思想:code
找到指定節點距離其餘節點的最短距離,也就是說該算法找的只是1個節點的最短距離。先指定一個初始節點x,並標記爲已訪問,而後初始化改節點距離其餘節點的距離,接着找到距離最近的一個節點m,標記爲已訪問,而後計算通過m作中介,是否縮短了節點x到其餘未訪問節點的距離,有縮短則更性。即:dis[i] > dis[m]+edge[m][i] 那麼dis[i] = dis[m]+edge[m][i] 。orm
Dijkstra算法的過程和Kruskal算法(最小生成樹)有些相似,都在尋找最小的問題,而後更新全局的距離。不過Dijkstra每次找到的是距離最近的點,而Kruskal找到的是最短的邊。blog
public void dijkstra(int x) { int pos = x; int join[] = new int[n + 1]; int pre[] = new int[n + 1]; pre[x] = 0; join[x] = 1; for (int i = 1; i <= n; i++) { // 初始化dis if (join[i] == 0) { dis[i] = data[pos][i]; } } for (int i = 0; i < n - 1; i++) { //除開起始點,須要查找n-1次 int min = max; for (int j = 1; j <= n; j++) { if (join[j] == 0 && dis[j] != 0 && min > dis[j]) { min = dis[j]; pos = j; } } join[pos] = 1; for (int j = 1; j <= n; j++) { if (join[j] == 0 && dis[j] > dis[pos] + data[pos][j]) { dis[j] = dis[pos] + data[pos][j]; pre[j] = pos; // 記錄下前置節點,用於輸出路徑 } } } for (int i = 1; i <= n; i++) { if (i == x) { continue; } System.out.println(String.format("%s -> %s: %s", x, i, dis[i])); } for (int i = 1; i <= n; i++) { int preN = pre[i]; if (preN > 0) { System.out.println(String.format("%d pre node is %d", i, preN)); } else { System.out.println(String.format("%d has no pre node", i)); } } }