1. 程式人生 > >Dijkstra演算法(三)之 Java詳解

Dijkstra演算法(三)之 Java詳解

/*
 * Dijkstra最短路徑。
 * 即,統計圖中"頂點vs"到其它各個頂點的最短路徑。
 *
 * 引數說明:
 *       vs -- 起始頂點(start vertex)。即計算"頂點vs"到其它頂點的最短路徑。
 *     prev -- 前驅頂點陣列。即,prev[i]的值是"頂點vs"到"頂點i"的最短路徑所經歷的全部頂點中,位於"頂點i"之前的那個頂點。
 *     dist -- 長度陣列。即,dist[i]是"頂點vs"到"頂點i"的最短路徑的長度。
 */
public void dijkstra(int vs, int[] prev, int[] dist) {
    // flag[i]=true表示"頂點vs"到"頂點i"的最短路徑已成功獲取
    boolean[] flag = new boolean[mVexs.length];

    // 初始化
    for (int i = 0; i < mVexs.length; i++) {
        flag[i] = false;          // 頂點i的最短路徑還沒獲取到。
        prev[i] = 0;              // 頂點i的前驅頂點為0。
        dist[i] = mMatrix[vs][i];  // 頂點i的最短路徑為"頂點vs"到"頂點i"的權。
    }

    // 對"頂點vs"自身進行初始化
    flag[vs] = true;
    dist[vs] = 0;

    // 遍歷mVexs.length-1次;每次找出一個頂點的最短路徑。
    int k=0;
    for (int i = 1; i < mVexs.length; i++) {
        // 尋找當前最小的路徑;
        // 即,在未獲取最短路徑的頂點中,找到離vs最近的頂點(k)。
        int min = INF;
        for (int j = 0; j < mVexs.length; j++) {
            if (flag[j]==false && dist[j]<min) {
                min = dist[j];
                k = j;
            }
        }
        // 標記"頂點k"為已經獲取到最短路徑
        flag[k] = true;

        // 修正當前最短路徑和前驅頂點
        // 即,當已經"頂點k的最短路徑"之後,更新"未獲取最短路徑的頂點的最短路徑和前驅頂點"。
        for (int j = 0; j < mVexs.length; j++) {
            int tmp = (mMatrix[k][j]==INF ? INF : (min + mMatrix[k][j]));
            if (flag[j]==false && (tmp<dist[j]) ) {
                dist[j] = tmp;
                prev[j] = k;
            }
        }
    }

    // 列印dijkstra最短路徑的結果
    System.out.printf("dijkstra(%c): \n", mVexs[vs]);
    for (int i=0; i < mVexs.length; i++)
        System.out.printf("  shortest(%c, %c)=%d\n", mVexs[vs], mVexs[i], dist[i]);
}