最大堆是最大整過(guò)(guo)一種特殊的完全二叉樹(shù),它的堆建(T_T)的完每個(gè)節點(diǎn)的值都大于或等于其子節點(diǎn)的值,在最大堆中,立過(guò)立初父節點(diǎn)的程建程值總是(⊙_⊙)大于或等于其子節點(diǎn)的值,最大堆通常用于實(shí)現優(yōu)先隊列,始堆其中優(yōu)先級最高的最大整過(guò)元素總是位于堆的頂部。
1. 將數組轉換為最大堆
我們需要找到數組的程建程最后一個(gè)非葉子節點(diǎn),這個(gè)節點(diǎn)(°□°)的始堆索引為`n/2`,我們從這個(gè)節點(diǎn)??開(kāi)始,最大整過(guò)向下遍歷數組,堆建的完對于每個(gè)節點(diǎn),立過(guò)立初我們將其與其子節點(diǎn)進(jìn)(°ロ°) !行比較,程建程如果它小于其任何一個(gè)子節點(diǎn),始堆我們就交換它和該子節點(diǎn)的位置,這個(gè)過(guò)程會(huì )一直持續到根節點(diǎn)。
以下是(°ロ°) !建立最大堆的Python代碼:
def build_max_heap(arr): n = len(arr) for i in range(n//2, -1, -1): heapify(arr, n, i) return arrdef heapify(arr, n, i): largest = i left = 2 * i + 1 right = 2 * i + 2 if left < n and arr[i] < ar?r[left]: largest = left if righヽ(′ー`)ノt < n and arr[largest](′;ω;`) <??; arr[right]: larg(′_ゝ`)est = right if larges??t != i: arr[i], arr[largest] = arr[??(′?_?`)largest], arr[i] heapify(arr, n, largest)
在這個(gè)代碼中,`build_max_h(′▽?zhuān)?)eap`函數接受一個(gè)數組作為參數,然后調用`heapify`函數來(lái)建立最大堆,`heapify`函數接受一個(gè)數組、數組的長(cháng)度和一個(gè)索引作為參數,然后它會(huì )檢查當前節點(diǎn)是否滿(mǎn)足最大堆的性質(zhì),如果不滿(mǎn)足,它就會(huì )對當前節點(diǎn)進(jìn)行下沉操作,直到滿(mǎn)足最大堆的性(′_ゝ`)質(zhì)為止。
1. 問(wèn):為什么我們需要從最后一個(gè)非葉子節點(diǎn)開(kāi)始建立最大堆?
答:因為最后一個(gè)非葉子節點(diǎn)是最大的葉子節點(diǎn)的父節點(diǎn),如果我們從這個(gè)節點(diǎn)開(kāi)始建立最大堆,那么我們就可以保證所有的(de)葉子節點(diǎn)都是最大的。
2. 問(wèn):為什么我們在交換節點(diǎn)(dian)后需要再次檢查堆的性質(zhì)?
答:因為在交換節點(diǎn)后,我們可能會(huì )破壞堆的性質(zhì),如果我們在交換節點(diǎn)后(hou)發(fā)現,新的根節點(diǎn)的值小于其子節點(diǎn)的值,那么我們就需要再次交換這兩個(gè)節點(diǎn)的位置,這個(gè)過(guò)程會(huì )一直持續到堆滿(mǎn)足最大堆的性質(zhì)為止。
3. 問(wèn):為什么我們需要使用`heapify`函數來(lái)建立最大堆?
答:因為`heapify`函數可以幫助我們確保每個(gè)節點(diǎn)都滿(mǎn)足最大堆的性質(zhì),如果我們直接交換節點(diǎn)的位置,那么我們可能會(huì )破壞堆的性質(zhì),通過(guò)使用`heapify`函數,我們可以確保每次交換節點(diǎn)的位置后,都會(huì )重新檢查并調整堆,以確保它滿(mǎn)足最大堆的性質(zhì)。
4. 問(wèn):為什么我們需要在`heapify`函數中使用遞歸?
答:因為我們需要確保每個(gè)節點(diǎn)都滿(mǎn)足最大堆的性質(zhì),如果我們只交換了當前節點(diǎn)的位置,ヾ(′?`)?而沒(méi)有檢查和調整其他節點(diǎn)的位置,那么我們??可能會(huì )破壞堆的性質(zhì),通過(guò)使用遞歸,我們可以確保每次交換節點(diǎn)的位置后,都會(huì )重新檢查并調整整個(gè)堆,以確保它滿(mǎn)足最大堆的性質(zhì)。