30
11 11 第第第第Heaps Heaps 11-1 11-1 堆堆堆堆堆 堆堆堆堆堆 11-2 11-2 堆堆堆堆堆堆 堆堆堆堆堆堆 11-3 11-3 堆堆堆堆堆 堆堆堆堆堆 11-4 11-4 堆堆堆堆 堆堆堆堆

第 11 章 堆積(Heaps)

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: 第 11 章  堆積(Heaps)

第第 1111 章 章 堆積(堆積( HeapsHeaps))

• 11-1 11-1 堆積的基礎堆積的基礎• 11-2 11-2 建立最大堆積建立最大堆積• 11-3 11-3 堆積排序法堆積排序法• 11-4 11-4 優先佇列優先佇列

Page 2: 第 11 章  堆積(Heaps)

11-1 11-1 堆積的基礎堆積的基礎 -- 說明說明• 「堆積」(「堆積」( HeapHeap )是一棵特殊二元樹,)是一棵特殊二元樹,

這棵二元樹必須滿足一些條件,如下所示:這棵二元樹必須滿足一些條件,如下所示:– 堆積是一棵完整二元樹。堆積是一棵完整二元樹。– 在堆積的每個父節點都比其左右子節點的資料在堆積的每個父節點都比其左右子節點的資料

大或相等。大或相等。

Page 3: 第 11 章  堆積(Heaps)

11-1 11-1 堆積的基礎堆積的基礎 -- 最大堆積最大堆積• 在堆積的節點中,最大值是根節點在堆積的節點中,最大值是根節點 99 ,所有子節,所有子節

點的資料都等於或比父節點小,這種堆積稱為點的資料都等於或比父節點小,這種堆積稱為「最大堆積」(「最大堆積」( Max HeapMax Heap ),如下圖所示:),如下圖所示:

Page 4: 第 11 章  堆積(Heaps)

11-1 11-1 堆積的基礎堆積的基礎 -- 最小堆積最小堆積• 反過來,如果根節點的資料是最小,所有反過來,如果根節點的資料是最小,所有

子節點的資料都等於或比父節點大,稱為子節點的資料都等於或比父節點大,稱為「最小堆積」(「最小堆積」( Min HeapMin Heap ),如下圖所),如下圖所示:示:

Page 5: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 -- 實作實作• 最大堆積是一棵完整二元樹,除了最高階最大堆積是一棵完整二元樹,除了最高階

層外,它是一棵完滿二元樹(層外,它是一棵完滿二元樹( Full Binary Full Binary TreeTree ),在實作上可以使用陣列來儲存第),在實作上可以使用陣列來儲存第11-111-1 節的最大堆積,如下圖所示:節的最大堆積,如下圖所示:

Page 6: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 -- 索引計算索引計算• heap[]heap[] 陣列儲存堆積資料,陣列儲存堆積資料, heap_lenheap_len 是是

目前堆積的元素數,索引值是從目前堆積的元素數,索引值是從 11 開始,開始,索引值索引值 00 並沒有使用,此時堆積節點的索並沒有使用,此時堆積節點的索引值計算,如下所示:引值計算,如下所示:右子節點索引 右子節點索引 = = 父節點索引 父節點索引 * * 2 + 12 + 1

左子節點索引 左子節點索引 = = 父節點索引 父節點索引 * * 22父節點索引 父節點索引 = = 子節點索引 子節點索引 / 2/ 2

Page 7: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 -- 插入節點插入節點(( 說明說明 ))

• 在最大堆積插入節點,首先將節點插入在最大堆積插入節點,首先將節點插入heap[]heap[] 陣列的最後,也就是插入成為二元陣列的最後,也就是插入成為二元樹的葉節點。樹的葉節點。

• 然後與父節點進行比較,往上一一和其父然後與父節點進行比較,往上一一和其父節點比較,就可以將二元樹調整成為堆積。節點比較,就可以將二元樹調整成為堆積。

Page 8: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 --插入節點插入節點(( 圖例圖例 1)1)

• 左邊的二元樹插入節點左邊的二元樹插入節點 99 ,首先插入在陣,首先插入在陣列列 heap_len+1heap_len+1 的索引位置,然後與其父的索引位置,然後與其父節點節點 55 比較,因為比較大,所以對調,如比較,因為比較大,所以對調,如下圖所示:下圖所示:

Page 9: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 --插入節點插入節點(( 圖例圖例 2)2)

• 因為節點因為節點 99 比較大,所以交換,最後和根比較大,所以交換,最後和根節點節點 88 進行比較,比較大所以交換,最後進行比較,比較大所以交換,最後就可以重建成堆積。函數就可以重建成堆積。函數 shiftUp()shiftUp() 就可就可以向上調整節點來重建堆積。以向上調整節點來重建堆積。

Page 10: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 -- 取出最大節取出最大節點點 (( 說明說明 ))

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

Page 11: 第 11 章  堆積(Heaps)

11-2 11-2 建立最大堆積建立最大堆積 -- 取出最大節取出最大節點點 (( 圖例圖例 ))

• 首先刪除根節點首先刪除根節點 99 ,並且將它取代成最後一個節,並且將它取代成最後一個節點點 55 ,然後從上至下,比較其子節點,因為比左,然後從上至下,比較其子節點,因為比左子節點小,所以交換,然後再與子節點比較,比子節點小,所以交換,然後再與子節點比較,比左子節左子節 66 小,所以交換即可完成堆積的重建。小,所以交換即可完成堆積的重建。

Page 12: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 說明說明• 「堆積排序法」(「堆積排序法」( Heap SortHeap Sort )是一種樹)是一種樹

狀結構的排序法,因為最大堆積的根節點狀結構的排序法,因為最大堆積的根節點就是最大的元素,換句話說,當我們將根就是最大的元素,換句話說,當我們將根節點移去後,只需將剩下節點重建成堆積,節點移去後,只需將剩下節點重建成堆積,此時第此時第 22 大節點就是根節點,重覆此操作,大節點就是根節點,重覆此操作,等到輸出所有根節點資料後,就可以完成等到輸出所有根節點資料後,就可以完成排序,這就是堆積排序法。排序,這就是堆積排序法。

Page 13: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 將二元樹建將二元樹建立堆積立堆積

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

Page 14: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立堆積的建立堆積的演算法演算法

• 將二元樹的陣列表示法建立成堆積,是從將二元樹的陣列表示法建立成堆積,是從二元樹陣列二元樹陣列 heap[]heap[] 的中間索引值往回調整,的中間索引值往回調整,依序往回調整的過程中,可以處理所有的依序往回調整的過程中,可以處理所有的葉節點,其步驟如下所示:葉節點,其步驟如下所示:– Step 1Step 1 :從最後:從最後 11 個父節點到第個父節點到第 11 個父節點個父節點

逐一執行操作,如下:逐一執行操作,如下:• (1) (1) 找出左、右子節點中,資料最大的節點和此節找出左、右子節點中,資料最大的節點和此節

點比較,如下:點比較,如下:– 1) 1) 如果節點比較大,沒有問題滿足堆積性質。如果節點比較大,沒有問題滿足堆積性質。– 2) 2) 如果節點比較小,交換父子節點值。如果節點比較小,交換父子節點值。

• (2) (2) 如果有交換,交換的父節點需要重覆步驟如果有交換,交換的父節點需要重覆步驟 (1)(1)的操作。的操作。

Page 15: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 11

• 首先找到最後首先找到最後 11 個父節點,即索引值個父節點,即索引值 9/2 = 49/2 = 4(整數除法),找到最後(整數除法),找到最後 11 個父節點是節點個父節點是節點 88 ,,可以發現其右子節點可以發現其右子節點 99 比它大,所以交換這兩個比它大,所以交換這兩個節點,如下圖所示:節點,如下圖所示:

Page 16: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 22

• 接著處理的是索引值接著處理的是索引值 33 的節點的節點 44 ,因為右子節點,因為右子節點比較大,所以交換這兩個節點,如下圖所示:比較大,所以交換這兩個節點,如下圖所示:

Page 17: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 33

• 然後是索引值然後是索引值 22 的節點的節點 66 ,此時是左子節點比較,此時是左子節點比較大,交換這兩個節點,如下圖所示:大,交換這兩個節點,如下圖所示:

Page 18: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 44

• 因為交換索引值因為交換索引值 44 的節點的節點 66 尚有子節點,繼續比尚有子節點,繼續比較其左、右子節點,結果左子節點較其左、右子節點,結果左子節點 88 比較大,所比較大,所以再次交換這兩個節點,如下圖所示:以再次交換這兩個節點,如下圖所示:

Page 19: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 55

• 最後調整的是索引值最後調整的是索引值 11 的根節點,可以發現其左的根節點,可以發現其左子節點子節點 99 比較大,所以交換根節點和其左子節點,比較大,所以交換根節點和其左子節點,如下圖所示:如下圖所示:

Page 20: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 66

• 索引值索引值 22 的節點的節點 55 尚有子節點,繼續比較其左右尚有子節點,繼續比較其左右子節點,結果是左子節點子節點,結果是左子節點 88 比較大,再次交換這比較大,再次交換這兩個節點,如下圖所示:兩個節點,如下圖所示:

Page 21: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 建立過程建立過程 77

• 接著索引值接著索引值 44 的節點的節點 55 仍然有子節點,比較結果仍然有子節點,比較結果是右子節點是右子節點 66 比較大,繼續交換這兩個節點,結比較大,繼續交換這兩個節點,結束二元樹的調整,建立的二元樹就是堆積,如下束二元樹的調整,建立的二元樹就是堆積,如下圖所示:圖所示:

Page 22: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 演算法演算法• 在建立好堆積後,就可以執行堆積排序,在建立好堆積後,就可以執行堆積排序,

堆積排序法的操作步驟,如下所示:堆積排序法的操作步驟,如下所示:– Step 1Step 1 :從二元樹調整節點建立成堆積。:從二元樹調整節點建立成堆積。– Step 2Step 2 :在輸出堆積的根節點後,將剩下的二:在輸出堆積的根節點後,將剩下的二

元樹節點重建成堆積。元樹節點重建成堆積。– Step 3Step 3 :重覆操作直到所有節點都已經輸出。:重覆操作直到所有節點都已經輸出。

Page 23: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 排序過程排序過程 11

• 堆積排序是將根節點刪除,但是並非真的刪除節堆積排序是將根節點刪除,但是並非真的刪除節點,而是和最後點,而是和最後 11 個陣列元素交換,索引值個陣列元素交換,索引值 99 是是刪除的節點,如下圖所示:刪除的節點,如下圖所示:

Page 24: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 排序過程排序過程 22

• 將索引值將索引值 11 到到 88 的節點視為一顆新的二元樹,這的節點視為一顆新的二元樹,這棵二元樹除根節點外都滿足堆積特性,所以只需棵二元樹除根節點外都滿足堆積特性,所以只需調整索引值調整索引值 11 的根節點,使之滿足堆積特性,就的根節點,使之滿足堆積特性,就可以重新建立堆積,調整結果如下圖所示:可以重新建立堆積,調整結果如下圖所示:

Page 25: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 排序過程排序過程 33

• 繼續將索引值繼續將索引值 11 的節點的節點 88 和索引值和索引值 88 的節點的節點 11 交交換,然後將索引值換,然後將索引值 11 到到 77 視為一棵二元樹且重新視為一棵二元樹且重新建立堆積,如下圖所示:建立堆積,如下圖所示:

Page 26: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 排序過程排序過程 44

• 現在已經排序好兩個元素,繼續堆積排序的處理,現在已經排序好兩個元素,繼續堆積排序的處理,交換節點交換節點 77 和最後索引值和最後索引值 77 ,將索引值,將索引值 11 到到 66 視視為一棵二元樹且重新建立堆積,如下圖所示:為一棵二元樹且重新建立堆積,如下圖所示:

Page 27: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 排序過程排序過程 55

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

Page 28: 第 11 章  堆積(Heaps)

11-3 11-3 堆積排序法堆積排序法 -- 執行效率執行效率• 堆積排序法的執行效率是當排序的資料個堆積排序法的執行效率是當排序的資料個

數為數為 nn 時,堆積排序的主迴圈一共執行時,堆積排序的主迴圈一共執行 n-n-11 次次 shiftDown()shiftDown() 函數,每次執行函數,每次執行shiftDwon()shiftDwon() 函數的效率為樹高即函數的效率為樹高即 Log nLog n ,,可以得到執行效率為可以得到執行效率為 O(n Log n)O(n Log n) 。。

• 堆積排序法不需要額外的記憶體空間,不堆積排序法不需要額外的記憶體空間,不過這種排序法不具有穩定性,因為在調整過這種排序法不具有穩定性,因為在調整根節點時,有可能交換相同鍵值的元素。根節點時,有可能交換相同鍵值的元素。

Page 29: 第 11 章  堆積(Heaps)

11-4 11-4 優先佇列優先佇列 -- 說明說明• 優先佇列(優先佇列( Priority QueuePriority Queue )儲存的每一個元)儲存的每一個元

素會指定一個優先權(素會指定一個優先權( PriorityPriority ),取出元素並),取出元素並不是取出最先存入的元素,而是最高優先權的元不是取出最先存入的元素,而是最高優先權的元素。素。

• 例如:在醫院的急診室陸續送入的病患中,並不例如:在醫院的急診室陸續送入的病患中,並不是先送入的先醫冶,而是最嚴重的病患先醫冶,是先送入的先醫冶,而是最嚴重的病患先醫冶,如下圖所示:如下圖所示:

Page 30: 第 11 章  堆積(Heaps)

11-4 11-4 優先佇列優先佇列 -- 實作實作• 在在 CC 語言實作優先佇列的最佳資料結構就語言實作優先佇列的最佳資料結構就

是最大堆積,存入佇列就是將元素插入堆是最大堆積,存入佇列就是將元素插入堆積,取出佇列元素,就是取得最大堆積的積,取出佇列元素,就是取得最大堆積的根節點,也就是最高優先權的元素。優先根節點,也就是最高優先權的元素。優先佇列的相關函數說明,如下表所示:佇列的相關函數說明,如下表所示:

函數 說明int isPriorityQueueEmpty() 檢查優先佇列是否是空的,如果是,傳回 1,

否則為 0

void enqueue(int d) 將參數的元素存入優先佇列,也就是將元素插入堆積

int dequeue() 從優先佇列取出元素,取出的是目前佇列中最高優先權的元素,也就是堆積的根節點