說到堆就必須要說二叉樹,二叉樹指每個節點最多只能包含兩個子節點的樹。二叉樹常用的實現為二叉搜尋樹(binarysearchtree)和二叉堆(binaryheap)
這裡不再對樹的概念進行贅述,有需求的自行google,二叉堆其實對應著一棵完全二叉樹,最後一層除外。因此使得乙個堆可以利用陣列來儲存,二叉堆又分為大根堆和小根堆,下圖展示了乙個大根堆與陣列的對應。
因此可以很簡單的得到堆節點所對應的陣列。 :banana:
堆排序就是把最大堆堆頂的最大數取出,將剩餘的堆繼續調整為最大堆,再次將堆頂的最大數取出,這個過程持續到剩餘數只有乙個時結束。在堆中定義以下幾種操作:
通俗的解釋就是:最大堆調整(max-heapify)其實就是一次《下沉》的過程,建立最大堆(build-max-heap)就是《迴圈》每個節點進行最大堆調整,堆排序(heap-sort)就是每次建立完最大堆之後需要將最大元素《分離》。
一句話概括:迴圈樹的每乙個節點進行下沉,然後分離,繼續迴圈。:tomato:
下圖展示了一次下沉的過程:
普通的佇列滿足先進先出,而優先佇列滿足每次出佇列的都是優先順序最高的元素。 :strawberry:
常見的優先佇列有三種實現方式:
因為優先佇列每次poll只需要最大優先順序的元素,所以不需要維持整棵二叉堆的有序,只需要維持根節點滿足最大優先順序即可。所以只需要對根節點進行一次堆排序的最大堆調整(max-heapify)即可。
//add方法也就是直接呼叫offer方法
public
boolean
offer
(e e)
//上浮分為兩種情況,判斷是否設定了comparator
private
void
siftup
(int k, e x)
//我們只分析這種沒有設定comparator的方法,另一種模擬
private
void
siftupcomparable
(int k, e x)
//將節點賦值到正確的上浮位置
queue[k] = key;
}//poll方法
public e poll
()
//下沉方法的實現與上浮類似,就不贅述了。
複製**
優先佇列與堆排序
許多應用程式在資料處理是,需要有序的處理資料,但是不一定要求他們全部有序,或著是不一定要一次就將整個資料進行排序。例如有些我們收集了一些元素,然後處理這些元素中的最大值。這個時候,對這兒陣列進行排序沒有必要,這就引出我們今天介紹的優先佇列。優先佇列時一種抽象資料型別,其最重要的操作就是刪除最大元素和...
優先佇列 堆排序
一種支援刪除最大元素和插入元素兩種操作的資料結構叫做優先佇列。實現棧or佇列與實現優先佇列的最大不同在於效能的要求。對於棧和佇列,我們實現能在常數時間完成所有操作 而優先佇列,插入元素和刪除最大元素這兩個操作在最壞情況下需要線性時間完成 優先佇列的各種實現在在最壞情況下執行時間的增長數量級 資料結構...
堆排序 優先佇列
1.堆排序 a.堆的定義 n個元素序列當且僅當滿足以下關係時,稱之為堆。ki k2i且ki k2i 1 小根堆 ki k2i且ki k2i 1 大根堆 以下針對最大堆 b.維護堆的性質 max heapify通過讓a i 的值在最大堆中 逐級下降 a i 的值小於其左右孩子的值時 從而使得以i為根結...