知識點7 堆

2021-10-03 04:57:49 字數 3472 閱讀 3105

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)

(證明可參考《演算法導論》)

//建堆

void

createheap()

}

另外,如果要刪除堆中的最大元素(也就是刪除堆頂元素),並讓其仍然保持堆的結構,那麼只需要最後乙個元素覆蓋堆頂元素,然後,然後對根結點進行向下調整即可。**如下:時間複雜度為 olo

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)

堆排序是指使用堆結構堆乙個序列進行排序。此處討論遞增排序想想為啥是遞增)的情況。

考慮對乙個堆而言,堆頂元素是最大的,因此在建堆完畢後,堆排序的直觀思路就是取出堆頂元素,然後將堆的最後乙個元素替換至堆頂,在進行一次針對堆頂元素的向下調整——如此重複,直到堆中只有乙個元素為止。

//堆排序

void

heapsort()

}

【pat a1098】insertion or heap sort

【堆排序】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中的任何乙個元素。那麼假設高度為權值,兩個堆可以形象...