3. 堆排序4. 題型訓練
5. 應用場景⭐⭐⭐⭐⭐
6. 參考文件
理解堆的乙個很好的例子就是我們的足球世界盃的賽制!我們的足球世界盃的賽制就是自底向上的。堆是一棵完全二叉樹,樹中每個結點的值都不小於(或不大於)其左右孩子結點的值。
堆一般用於優先佇列priority_queue
的實現,而優先佇列預設情況下使用的是大頂堆,因此本節以大頂堆為例,以下出現的堆均指大頂堆。
下面給出乙個大頂堆的例項:
那麼,對乙個給定的初始序列,怎樣把它建成乙個堆呢?
至此,建堆就完成了。那麼具體怎麼實現呢?
對完全二叉樹來說,比較簡潔的實現方法就是按照在前面說的,使用陣列來儲存完全二叉樹。
這樣結點就按層序儲存在了陣列中(⭐⭐⭐⭐⭐妙呀!!! )。其中第乙個結點將儲存在陣列的1號位(在前面的章節中講解過要設定起點為1),並且陣列i
號位表示的結點的左孩子就是2i
號位,而右孩子則是(2i+1)
號位。於是可以像下面這樣定義陣列來並表示堆:
回顧之前的建堆過程會發現,每次調整都是把結點從上往下的調整。const
int maxn =
100;
//heap為堆,n為元素個數
int heap[maxn]
,n =
10;
針對這種向下調整,調整方法是這樣的:
於是很容易可以寫出向下調整的**,顯然時間複雜度為 o(l
ogn)
o(logn)
o(logn
)。
那麼建堆的過程也就很容易了。假設序列中元素的個數為//對heap陣列在[low,high]範圍進行向下調整
//其中low為欲調整結點的陣列下標,high一般為堆的最後乙個元素的陣列下標
void
downadjust
(int low,
int high)
//如果孩子中最大的權值比欲調整結點i大
if(heap[j]
> heap[i]
)else
}}
n
,於是可以從n
2\frac n 22n
的下界開始倒著列舉結點,對每個遍歷到的結點i
進行[i,n]
範圍的調整。
建堆的**如下,時間複雜度為 o(n
)o(n)
o(n)
(證明可參考《演算法導論》)
另外,如果要刪除堆中的最大元素(也就是刪除堆頂元素),並讓其仍然保持堆的結構,那麼只需要最後乙個元素覆蓋堆頂元素,然後,然後對根結點進行向下調整即可。**如下:時間複雜度為 olo//建堆
void
createheap()
}
g(n)
olog(n)
olog(n
)。
那麼,如果想要往堆裡新增乙個元素,應當怎麼辦呢?可以把想要新增的元素放到陣列最後(也就是完全二叉樹的最後乙個結點後面),然後進行向上調整操作。//刪除堆頂元素
void
deletetop()
向上調整總是把欲調整結點與父親結點比較,如果權值比父親結點大,那麼就交換其與父親結點,這樣反覆比較,直到達到堆頂或是父親結點權值較大為止。往上調整的**如下,時間複雜度為 o(l
ogn)
o(logn)
o(logn
)
在此基礎上就很容易實現新增元素的**了://對heap陣列在[low,high]範圍進行向上調整
//其中low一般設定為1,high表示欲調整結點的陣列下標
void
upadjust
(int low,
int high)
else
}}
堆排序是指使用堆結構堆乙個序列進行排序。此處討論遞增排序(想想為啥是遞增)的情況。//新增元素x
void
insert
(int x)
考慮對乙個堆而言,堆頂元素是最大的,因此在建堆完畢後,堆排序的直觀思路就是取出堆頂元素,然後將堆的最後乙個元素替換至堆頂,在進行一次針對堆頂元素的向下調整——如此重複,直到堆中只有乙個元素為止。
【pat a1098】insertion or heap sort//堆排序
void
heapsort()
}
【堆排序】leetcode 215. kth largest element in an array
【分類思想+堆】leetcode 373. find k pairs with smallest sums
leetcode 347. top k frequent elements
leetcode 378. kth smallest element in a sorted matrix
pat a1147 heaps
只要涉及到了前k個最優值的問題,一般都要想到堆。(注意是堆,而不是堆排序!比如這個題目用的是堆,而不是堆排序,它們時間複雜度是有區別的。)
我覺得這句話說的有道理,因為堆恰好能每次求乙個最值,而不像其他排序演算法要全部排完才行!所以堆比較節約時間了。演算法筆記
堆知識點總結
堆中插入元素 堆中刪除元素 時間複雜度分析 設有n個資料元素的關鍵字為 k0,k1,kn 1 如果他們滿足以下的關係 ki k2i 1且ki k2i 2 或者ki k2i 1且ki k2i 2 i 0,1,向下取整 n 2 2 則稱為堆 heap 如果將此資料元素序列用一維陣列儲存,並將此陣列對應一...
7 鎖知識點
1,系統資源的競爭 2,程序推進順序非法 3,訊號量使用不當也會造成死鎖 4,死鎖產生的必要條件 1.互斥條件,2.不剝奪條件,3.請求和保持條件,4.迴圈等待條件 加鎖順序 執行緒按照一定的順序加鎖 加鎖時限 執行緒嘗試獲取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,並釋放自己占有的鎖 死...
對頂堆 知識點補充
原 處理動態中位數等問題,靈活運用了堆的性質,本質是維護兩個堆。大根堆q1 維護集合中較小值的部分的最大值。小根堆q2 維護集合中較大值的部分的最小值。注意到兩個堆中的元素各自是單調的,兩個堆間也是單調的。也就是說,q1中的任何乙個元素都不大於q2中的任何乙個元素。那麼假設高度為權值,兩個堆可以形象...