用例:
將一組數據從大到小進行排列 10, 16, 18, 12, 11, 13, 15, 17, 14, 19
size=10
步驟1.根據數組初始化堆
步驟2.從最後一個根節點( 下標為(size-1-1)/2 )開始往第一個根節點遍歷,依次將每個最小子樹排好序,建造一個小堆:
步驟3.進行堆排序:將堆數組的首位置和末位置的數據交換,縮小范圍 以--size大小的范圍將堆頂數據下調,完成建堆
理解了整個思想,我們就來看代碼:
先實現一個下調函數用來建堆,並對堆進行調整:(本案例是從大到小進行排序,所以建的是小堆;若是要從小到大進行排序,則要按照大堆思想進行實現,對代碼稍微進行改進即可)
//下調 void AdjustDown(int *array, int parent, int size) { int left = parent * 2 + 1; int right = left + 1; while (left < size) { // 比較左右孩子,保證下標left為最小的節點下標 if (right <size && array[right] < array[left]) { left = right; } // 如果父節點大於左右孩子中較小的節點時,就交換這兩個節點,要保證兩個子節點都大於父節點 if (left<size && array[parent]>array[left]) { // 交換之後還需繼續 將相對較大的數循環向下調 swap(array[left], array[parent]); parent = left; left = parent * 2 + 1; right = left + 1; } else { break; } } }
堆排序:按照圖說的步驟來寫代碼,首先要初始化一個堆數組並對它進行排序,之後再一步步將堆頂與有效堆尾數據進行交換,並逐漸縮小堆的size,一組有序的數據就排好了!
//堆排序 int* HeapSort(int *heap, int size) { for (int start = (size - 1 - 1) / 2; start >= 0; start--) { AdjustDown(heap, start, size); } for (int i = size - 1; i >= 0; --i) { swap(heap[0], heap[i]); AdjustDown(heap, 0, i); } return heap; }