1. 程式人生 > >堆排序(Heap Sort)- java實現

堆排序(Heap Sort)- java實現

學習自嚴蔚敏、吳偉民的《資料結構》-清華大學出版

過於複雜,理解的不夠透徹,只存放程式碼部分

1、建立堆:

/**
 * 由於使得陣列元素遞增排序,所以先建一個“大頂堆”,即先選得一個關鍵字為最大的記錄並與序列中最後一個記錄交換
 * 所以,每次訪問陣列會是n-i
 * @param arr-陣列元素
 * @param s-開始位置-0
 * @param m-結束位置-逐漸減1(從陣列長度開始)
 */
public static void heapAdjust(int[] arr, int s, int m) {
	// 已知arr[s~m]中的元素除arr[s]之外均滿足堆的定義,本函式調整arr[s]的元素,使arr[s~m]成為一個大頂堆(對其中元素而言)
	int rc = arr[s];
	// 相當於二叉樹,當前結點的下一層
	for (int j = 2 * s; j < m; j *= 2) {
		// 選出較大的結點
		if (j < m && arr[j] < arr[j + 1]) {
			++j;
		}
		// 若比第一個結點(根結點)小,則結束本次迴圈
		if (!(rc < arr[j])) {
			break;
		}
		// 說明比根結點大,將至向前移動
		arr[s] = arr[j];
		// 記錄當前空出的結點位置
		s = j;
	}
	// 將空出結點的位置存放之前的根結點
	arr[s] = rc;
}

2、通過上述方法將陣列排序(遞增)

public static void heapSort(int[] arr) {
	// 將最大數移到首位,並且是符合堆的定義
	// 把無序陣列建成大頂堆:從【arr.length / 2】開始向前遍歷,結束後便得到大頂堆
	for (int i = arr.length / 2; i >= 0; i--) {
		heapAdjust(arr, i, arr.length);
	}
	for (int i = arr.length - 1; i > 0; i--) {
		// 將堆頂元素(當前最大元素)和當前未經排序子序列arr[0~i]中最後一個記錄交換
		int temp = arr[0];
		arr[0] = arr[i];
		arr[i] = temp;
		// 將arr[0~i]重新調整為大頂堆
		heapAdjust(arr, 0, i - 1);
	}
}