堆排序的結構形態是用乙個陣列實現了乙個二叉樹,堆分為最大堆和最小堆兩種,最大堆指的是該二叉樹的任意乙個父節點都比其相連的子節點大,最小堆則反之。對於最大堆來說,其根節點就是整個堆的最大值。
那麼對於堆排序演算法來說,主要做的是兩件事,首先是建堆,之後可以通過堆來依次獲取大小有序的數值,每取乙個值都需要重新調整堆來保持堆的正確性。
建堆過程稍微複雜一些,以最大堆為例,首先【倒序遍歷】含有子節點的節點,【比較】其值與子節點的值,如果子節點的值更大的話,則該節點的值與其子節點的值進行【交換】。交換完成後,需要從子節點的位置繼續判斷其子節點是否比其大,如果是的話也進行交換,這樣依次【向下傳遞調整】,直到子節點不比父節點大或者已經到達葉子節點為止。
對於關鍵步驟已經通過【】標註出來了,整個建堆過程有點類似氣泡排序在二叉樹上面的實現。完成以上步驟就可以獲得乙個最大堆。
之後的步驟是獲取排序結果,**在實現的時候比較有意思了,首先取出堆頂的數,讓其與陣列最後乙個數進行交換,之後我們將陣列最後乙個數從堆裡面排除出去,之後從根節點開始,對堆做一次【向下傳遞調整】操作,那麼我們最大值就跑陣列最後面去了;第二次,我們再取堆頂的數,讓其與陣列最後第二個數進行交換,之後我們將陣列最後兩個數從堆裡面排除出去,之後從根節點開始,對堆做一次【向下傳遞調整】操作。這樣一次進行取數、交換、跳轉的操作,總共進行n-1次後,我們會發現我們的陣列已經以乙個從小到大的進行排序了。這就是堆排序的整個過程。
c++**實現如下
// 最大堆排序 -- 獲取從小到大排序的結果
#include
using
namespace
std;
void
swep
(int i, int j, int *unsortarray)
// 調整節點
void
adjustcurrent
(int index, int* unsortarray, int size)
if (unsortarray[index] < unsortarray[indexson1]
|| (hasnodeson2 && unsortarray[index] < unsortarray[indexson2]))
else
}else
//向下傳遞調整
adjustcurrent(index * 2 + witchsweped, unsortarray, size);
}}void
heapsort
(int *unsortarray, int size)
// 通過堆獲取排序結果
int currentindex = size - 1;
while(currentindex)
}int
main();
int size = sizeof(unsortarray)/sizeof(int);
cout
<<"before sort"
cout
cout
<<"after sort"
cout
0;}
排序演算法整理之堆排序
堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆是乙個近似完全二叉樹的結構,並同時滿足堆性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。堆排序的過程是 1.建立乙個堆 2.把堆首 最大值 和堆尾互換 3.把堆的尺寸縮小1,目的是把新的陣列頂端資料調整到相應位置 4...
排序演算法整理 5 堆排序
程式參考了clrs的 演算法導論 第六章 heap sort。由於最大堆和最小堆是對稱的,下文都說最大堆。1 堆的定義 最大堆就是這樣一種樹,每個節點而言,如果它有兒子,那麼此節點比它的兒子都大。需要注意的有兩點。首先,堆幾乎是一種完全二叉樹,也可能是不完全的,下面第4部分中的圖一。其次,如果要用陣...
整理排序演算法(五) 堆排序
堆排序 大頂堆 將記錄看成乙個順序儲存的二叉樹 先構建大頂堆,所有節點都比他的兒子大或者等於。第一步 從最後乙個非葉子節點開始比較,一直到根。構建大頂堆成功。第二步 根與最後的葉子節點交換位置 第三步 除去剛才的葉子節點,再次構建大頂堆,這個時候構建大頂堆只要從上往下層級遍歷就好。演算法效能 堆排序...