該模塊可以實現堆,是python自帶模塊。當需要使用堆這種數據結構時,可以不必自己編寫,直接調用該模塊的api,比較方便。
下面先簡單介紹一下堆。
堆(heap)
堆是一種用數組實現的二叉樹,具有以下特點:
- 堆中每個節點的值總是不大於或不小於其父節點的值
- 堆是一棵完全二叉樹
根節點最大的堆叫最大堆,根節點最小的堆叫最小堆。
因爲堆是完全二叉樹,所以其實現方式不像樹使用鏈式結構從父節點用指針指向子節點。在數組中,堆中某節點的左子節點是該節點索引乘2,右子節點是該節點索引乘2再加1,如下圖是一個最大堆:
上圖紅字是數組中的索引,堆的索引通常從1開始。可見左子節點索引是父節點的2倍,右子節點是父節點索引的2倍再加1。
堆的常見應用:
- 實現優先隊列,可以很容易找出最大值或最小值,並進行刪除操作。
- 堆排序
當heap中發生元素變動時,比如添加一個數值,該數可能會對heap結構產生影響,有的節點要改變位置。heapq模塊提供方法可以將一個列表轉換爲堆,可以直接增、刪節點,節點根據大小自動變換位置。
heapq模塊中的堆
- 索引從0開始。 這使得節點的索引與其子節點的索引之間的關係不太明顯,但由於Python中對象從0開始索引,因此更適合。
- 最小堆,即:heap[0]是最小項,heappop方法彈出最小項。
常用方法
heapq.heapify(x)
#將一個list原地轉換爲一個heap,即x按照heap結構排序。時間複雜度:O(len(x))
*注:*heap在python中類型還是list,一個空的list可以作爲heap的初始化。
heapq.heappop(x) -> x[0]
#從一個heap(list)中彈出頂部元素(最小值)
heapq.heappush(x,item)
#向一個heap中添加元素,自動排序
heapq.heapreplace(x,item) -> x[0]
#彈出並返回頂部元素,並添加新元素,排序。heap的大小不變。
示例
爲了方便演示,初始化一個列表x,下述方法按順序進行。
heapify
將輸入的list原地轉換爲heap,本質是進行了排序的操作。
import heapq
x=[4,5,6,1,7,2,8]
heapq.heapify(x)
x # [1, 4, 2, 5, 7, 6, 8] 1是頂部元素;4、2處於第二層;5、7、6、8處於第三層
heappop
import heapq
heapq.heappop(x) # 1
x # [2, 4, 6, 5, 7, 8] 將1彈出後,頂部元素變爲2
heappush
import heapq
heapq.heappush(x,3)
x # [2, 4, 3, 5, 7, 8, 6] 3進入堆中相應位置,對原結構也產生了影響
heapreplace
import heapq
heapq.heapreplace(x,1) # 2 將頂部元素彈出並返回
x # [1, 4, 3, 5, 7, 8, 6] 將1加入堆中,重新排序