數據結構:二叉完全樹(堆)

參考文章

堆常用來實現優先隊列。
用數組保存數據,而不是鏈表。

在隊列中,操作系統調度程序反覆提取隊列中第一個作業並運行,因爲實際情況中某些時間較短的任務將等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優先權。堆即爲解決此類問題設計的一種數據結構。

堆的實現通過構造二叉堆(binary heap),實爲二叉樹的一種(完全二叉樹
完全二叉樹:若設二叉樹的深度爲h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹

大根堆和小根堆

最大(最小)堆是一棵每一個節點的鍵值都不小於(大於)其孩子(如果存在)的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是一棵完全完全二叉樹,同時也是一棵最小樹。

將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。

  • 堆中任一子樹亦是堆。
  • 以上討論的堆實際上是二叉堆(Binary Heap),類似地可定義k叉堆。

如下圖所示,圖一爲最大堆,圖二爲最小堆:
image.png

基本操作

  • 上浮 shift_up;
  • 下沉 shift_down
  • 插入 push
  • 彈出 pop
  • 取頂 top
  • 堆排序 heap_sort

以小根堆爲例:
堆可以用數組存儲數據,如有數組:{8,5,2,9,3,7,1,4,6}
則可以構成堆:
image.png

可以發現:任意節點的左右孩子對應數組下標的一半爲其父節點對應的下標(5/24/22)。
注意:這裏下標從1開始計算而不是從0開始,因爲從0開始的話根節點的下標和子節點下標間就沒有了倍數關係(5/2 != 6/2)

上浮

從當前結點開始,和它的父親節點比較,若是比父親節點來的小,就交換,然後將當前詢問的節點下標更新爲原父親節點下標;否則退出。
image.png

下沉

經過上浮操作之後,下標3處節點的元素值如下圖所示
image.png

讓當前結點的左右兒子(如果有的話)作比較,哪個比較小就和它交換,並更新詢問節點的下標爲被交換的兒子節點下標,否則退出。

插入

每次插入的時候呢,都往最後一個插入,然後使它上浮。

彈出(刪除根節點元素)

讓根節點元素和尾節點進行交換,然後讓現在的根元素下沉就可以了。

取頂

根節點數組下標必定是 0,返回堆數組中下標爲 0 的元素即可。

堆排序

見算法 - 排序系列文章第六篇,同時用代碼實現上述對堆的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章