contributed by < steven1lung >
do_sift_up
這個函式所做的事情就是確認父節點是小於(或大於,看是 min-heap 還是 max-heap)當前的節點,如果是的話就不用變更,如果不是就要將父節點跟現在的節點互換。
因為往上互換後,換完節點的新的父節點又有可能會不符合 heap,所以要繼續檢查,故在最後一行又呼叫 do_sift_up(pidx, nr_items, h)
。
依照剛剛的想法,我們可以確認要繼續做遞迴的條件就是「父節點大於子節點」,所以我們可以使用一個 while
迴圈只要符合上述的條件就進行互換。
在 while
迴圈裡要有上述的條件外(父節點大於子節點),還要確認我們所找的父街點是合法的,所以要多加一個判斷式 parent(idx>=1
。
do_sift_up
是有問題的,會在父節點都比子節點還小時結束執行,導致不會繼續檢查上層的節點。所以要修改上述的 while
迴圈程式碼:
改成只要有找到父節點就會繼續執行,如果父節點小於子節點(符合 min-heap)那就會不執行交換,繼續往上找。
但是上述所說的情況只會發生在初始化這個 heap 的時候,如果是正常的 min-heap,原本插入前的 heap 就會是符合 min-heap 的節點了,就只需要判斷父節點跟子節點的大小跟交換後的關係。
如果要減少遞回或是迭代的次數,可以將初始化跟平常所呼叫的 sift_up
區分,讓平常所呼叫的不用繼續執行下去。