1. 程式人生 > >Java資料結構:單源最短路徑問題---Dijkstra演算法

Java資料結構:單源最短路徑問題---Dijkstra演算法

嚶擊長空

如圖:

思路:先任意找一個根節點,然後開始迴圈找連線該點所有邊,然後找到權值最小的一項,標記被訪問,然後再次迴圈找除了根節點和被訪問過的結點的邊,找到權值最小的。具體開註釋,非常詳細喲。

上程式碼:

public void shortesPath(int i) {
		int n = this.vertexCount(); // 圖的結點數
		boolean[] vset = new boolean[n]; // 已求出最短路徑的頂點集合,初始全為false;
		vset[i] = true; // 當前的開始結點為true
		int[] dist = new int[n]; // 最短路徑的長度
		int[] path = new int[n]; // 最短路徑終點的前一結點
		for (int j = 0; j < n; j++) { // 初始化dist和path
			dist[j] = this.weight(i, j);
			path[j] = (j != i && dist[j] < MAX_WEIGHT) ? i : -1;
		}
		for (int j = (i + 1) % n; j != i; j = (j + 1) % n) { // 開始尋找從i到各個結點的最短路徑,取餘為了使防止出現j比結點數i大的情況
			int mindist = MAX_WEIGHT, min = 0; // 定義路徑最小值和其下標
			for (int k = 0; k < n; k++) { // 開始尋找最小路徑
				if (!vset[k] && dist[k] < mindist) {// 如果沒有訪問過並且有路徑小於當前路徑的最小路徑
					mindist = dist[k]; // 跟新最小路徑和最小路徑的下標
					min = k;
				}
			}
			if (mindist == MAX_WEIGHT) {// 如果沒有其他最短路徑則此演算法結束。
				break;
			}
			vset[min] = true; // 設定最小結點訪問過
			for (int k = 0; k < n; k++) {// 更新i到其他結點的路徑
				if (!vset[k] && this.weight(min, k) < MAX_WEIGHT
						&& dist[min] + this.weight(min, k) < dist[k]) {// 如果沒有被訪問,並且小於初始路徑權值,更新路徑。
					dist[k] = dist[min] + this.weight(min, k);	//最小路徑+最小路徑結點到目的結點的權《=》i直接到目的結點的權。決定是否替換。
					path[k] = min;
				}
			}
		}
}