1 / 30

第 11 章 堆積(Heaps)

第 11 章 堆積(Heaps). 11-1 堆積的基礎 11-2 建立最大堆積 11-3 堆積排序法 11-4 優先佇列. 11-1 堆積的基礎 - 說明. 「堆積」( Heap )是一棵特殊二元樹,這棵二元樹必須滿足一些條件,如下所示: 堆積是一棵完整二元樹。 在堆積的每個父節點都比其左右子節點的資料大或相等。. 11-1 堆積的基礎 - 最大堆積. 在堆積的節點中,最大值是根節點 9 ,所有子節點的資料都等於或比父節點小,這種堆積稱為「最大堆積」( Max Heap ),如下圖所示:. 11-1 堆積的基礎 - 最小堆積.

ariana-dyer
Télécharger la présentation

第 11 章 堆積(Heaps)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第11章 堆積(Heaps) • 11-1 堆積的基礎 • 11-2 建立最大堆積 • 11-3 堆積排序法 • 11-4 優先佇列

  2. 11-1 堆積的基礎-說明 • 「堆積」(Heap)是一棵特殊二元樹,這棵二元樹必須滿足一些條件,如下所示: • 堆積是一棵完整二元樹。 • 在堆積的每個父節點都比其左右子節點的資料大或相等。

  3. 11-1 堆積的基礎-最大堆積 • 在堆積的節點中,最大值是根節點9,所有子節點的資料都等於或比父節點小,這種堆積稱為「最大堆積」(Max Heap),如下圖所示:

  4. 11-1 堆積的基礎-最小堆積 • 反過來,如果根節點的資料是最小,所有子節點的資料都等於或比父節點大,稱為「最小堆積」(Min Heap),如下圖所示:

  5. 11-2 建立最大堆積-實作 • 最大堆積是一棵完整二元樹,除了最高階層外,它是一棵完滿二元樹(Full Binary Tree),在實作上可以使用陣列來儲存第11-1節的最大堆積,如下圖所示:

  6. 11-2 建立最大堆積-索引計算 • heap[]陣列儲存堆積資料,heap_len是目前堆積的元素數,索引值是從1開始,索引值0並沒有使用,此時堆積節點的索引值計算,如下所示: 右子節點索引 = 父節點索引 * 2 + 1 左子節點索引 = 父節點索引 * 2 父節點索引 = 子節點索引 / 2

  7. 11-2 建立最大堆積-插入節點(說明) • 在最大堆積插入節點,首先將節點插入heap[]陣列的最後,也就是插入成為二元樹的葉節點。 • 然後與父節點進行比較,往上一一和其父節點比較,就可以將二元樹調整成為堆積。

  8. 11-2 建立最大堆積-插入節點(圖例1) • 左邊的二元樹插入節點9,首先插入在陣列heap_len+1的索引位置,然後與其父節點5比較,因為比較大,所以對調,如下圖所示:

  9. 11-2 建立最大堆積-插入節點(圖例2) • 因為節點9比較大,所以交換,最後和根節點8進行比較,比較大所以交換,最後就可以重建成堆積。函數shiftUp()就可以向上調整節點來重建堆積。

  10. 11-2 建立最大堆積-取出最大節點(說明) • 從堆積取出最大節點,以最大堆積來說,就是根節點,同樣的,當刪除根節點後,就需要重新調整來建立堆積。

  11. 11-2 建立最大堆積-取出最大節點(圖例) • 首先刪除根節點9,並且將它取代成最後一個節點5,然後從上至下,比較其子節點,因為比左子節點小,所以交換,然後再與子節點比較,比左子節6小,所以交換即可完成堆積的重建。

  12. 11-3 堆積排序法-說明 • 「堆積排序法」(Heap Sort)是一種樹狀結構的排序法,因為最大堆積的根節點就是最大的元素,換句話說,當我們將根節點移去後,只需將剩下節點重建成堆積,此時第2大節點就是根節點,重覆此操作,等到輸出所有根節點資料後,就可以完成排序,這就是堆積排序法。

  13. 11-3 堆積排序法-將二元樹建立堆積 • 如何將一棵二元樹建立成堆積,以二元樹陣列表示法為例的一棵二元樹,如下圖所示:

  14. 11-3 堆積排序法-建立堆積的演算法 • 將二元樹的陣列表示法建立成堆積,是從二元樹陣列heap[]的中間索引值往回調整,依序往回調整的過程中,可以處理所有的葉節點,其步驟如下所示: • Step 1:從最後1個父節點到第1個父節點逐一執行操作,如下: • (1) 找出左、右子節點中,資料最大的節點和此節點比較,如下: • 1) 如果節點比較大,沒有問題滿足堆積性質。 • 2) 如果節點比較小,交換父子節點值。 • (2) 如果有交換,交換的父節點需要重覆步驟(1)的操作。

  15. 11-3 堆積排序法-建立過程1 • 首先找到最後1個父節點,即索引值9/2 = 4(整數除法),找到最後1個父節點是節點8,可以發現其右子節點9比它大,所以交換這兩個節點,如下圖所示:

  16. 11-3 堆積排序法-建立過程2 • 接著處理的是索引值3的節點4,因為右子節點比較大,所以交換這兩個節點,如下圖所示:

  17. 11-3 堆積排序法-建立過程3 • 然後是索引值2的節點6,此時是左子節點比較大,交換這兩個節點,如下圖所示:

  18. 11-3 堆積排序法-建立過程4 • 因為交換索引值4的節點6尚有子節點,繼續比較其左、右子節點,結果左子節點8比較大,所以再次交換這兩個節點,如下圖所示:

  19. 11-3 堆積排序法-建立過程5 • 最後調整的是索引值1的根節點,可以發現其左子節點9比較大,所以交換根節點和其左子節點,如下圖所示:

  20. 11-3 堆積排序法-建立過程6 • 索引值2的節點5尚有子節點,繼續比較其左右子節點,結果是左子節點8比較大,再次交換這兩個節點,如下圖所示:

  21. 11-3 堆積排序法-建立過程7 • 接著索引值4的節點5仍然有子節點,比較結果是右子節點6比較大,繼續交換這兩個節點,結束二元樹的調整,建立的二元樹就是堆積,如下圖所示:

  22. 11-3 堆積排序法-演算法 • 在建立好堆積後,就可以執行堆積排序,堆積排序法的操作步驟,如下所示: • Step 1:從二元樹調整節點建立成堆積。 • Step 2:在輸出堆積的根節點後,將剩下的二元樹節點重建成堆積。 • Step 3:重覆操作直到所有節點都已經輸出。

  23. 11-3 堆積排序法-排序過程1 • 堆積排序是將根節點刪除,但是並非真的刪除節點,而是和最後1個陣列元素交換,索引值9是刪除的節點,如下圖所示:

  24. 11-3 堆積排序法-排序過程2 • 將索引值1到8的節點視為一顆新的二元樹,這棵二元樹除根節點外都滿足堆積特性,所以只需調整索引值1的根節點,使之滿足堆積特性,就可以重新建立堆積,調整結果如下圖所示:

  25. 11-3 堆積排序法-排序過程3 • 繼續將索引值1的節點8和索引值8的節點1交換,然後將索引值1到7視為一棵二元樹且重新建立堆積,如下圖所示:

  26. 11-3 堆積排序法-排序過程4 • 現在已經排序好兩個元素,繼續堆積排序的處理,交換節點7和最後索引值7,將索引值1到6視為一棵二元樹且重新建立堆積,如下圖所示:

  27. 11-3 堆積排序法-排序過程5 • 等到堆積的全部節點都輸出後,可以得到最後的陣列內容,就是堆積排序法的排序結果。如下圖所示:

  28. 11-3 堆積排序法-執行效率 • 堆積排序法的執行效率是當排序的資料個數為n時,堆積排序的主迴圈一共執行n-1次shiftDown()函數,每次執行shiftDwon()函數的效率為樹高即Log n,可以得到執行效率為O(n Log n)。 • 堆積排序法不需要額外的記憶體空間,不過這種排序法不具有穩定性,因為在調整根節點時,有可能交換相同鍵值的元素。

  29. 11-4 優先佇列-說明 • 優先佇列(Priority Queue)儲存的每一個元素會指定一個優先權(Priority),取出元素並不是取出最先存入的元素,而是最高優先權的元素。 • 例如:在醫院的急診室陸續送入的病患中,並不是先送入的先醫冶,而是最嚴重的病患先醫冶,如下圖所示:

  30. 11-4 優先佇列-實作 • 在C語言實作優先佇列的最佳資料結構就是最大堆積,存入佇列就是將元素插入堆積,取出佇列元素,就是取得最大堆積的根節點,也就是最高優先權的元素。優先佇列的相關函數說明,如下表所示:

More Related