咱們能夠把任意優先隊列編程一種排序方法。將全部元素插入一個查找最小元素的優先隊列,而後再重複調用刪除最小元素的操做來將他們按順序刪除。用無序數組實現的優先隊列這麼作至關於一次選擇排序。用基於堆的優先隊列排序至關於我今天要說的——堆排序。java
堆排序能夠分爲兩個階段:①堆的構造 ②下沉排序算法
堆的構造:①用swim()能夠在與NlogN成正比的時間內完成這項操做。只需從左至又遍歷數組,②挨個把元素插入到堆中。編程
②用sink()只需少於2N次比較和小於N次交換。顯然下沉操做更加高效。將每一個節點下沉排序,即經過此算法可使只有目前節點做爲根節點的堆進行有序化,顯然數組中N/2以後的節點都不存在新的子葉,故下沉函數從N/2之前從右至左挨個實現當前子堆的有序化,最終可實現整個堆的有序化。數組
下沉排序:將堆中最大元素放到最後,使堆的規模減少一,再循環次步驟,直至堆中不存在元素。緩存
堆排序的代碼實現:函數
public static void sort(Comparable [] a) { int N=a.length; for(int k=N/2;k>=1;k--) { //構造堆,即實現堆的有序化 sink(a,k,n); } while(N>1) { exch(a,1,N--); //交換根節點和堆中最後一個元素的位置,即將目前堆中最大的元素放於對的最後 sink(a,1,N); //從新進行堆的有序化 } }
性能:將N個元素排序,堆排序只須要少於(2NlgN+2N)次比較(以及一半次數的交換)。性能
堆排序是咱們所知的惟一可以同時最優地利用空間和時間的方法。code
可是現代系統中應用很少,由於它不多和數組中相鄰的元素比較,即沒法利用緩存,因此緩存未命中的次數要遠高於不少算法。排序
另外一方面它也十分重要,由於它能在插入操做和刪除最大元素操做的混合的動態場景中保證對數級別的運行時間。隊列