Python中的堆实现:heapq 模块——利用堆结构实现快速访问数据流中的中位数
堆結構
堆結構是一種優先隊列,可以以任意順序添加對象,并隨時查找或刪除最小(大)的元素,或者查找和刪除前 K 個最小(大)元素。相比于列表方法min() / max(),這樣做的效率要高得多。
堆結構是一種特殊的完全二叉樹(除了葉子節點層外,其余層節點數均達到最大值,而葉子節點層所有節點都集中在左側)。根節點的值不大于(小于)其子節點的值,并且子節點也服從這種特性。根節點值不大于子節點的堆稱為小根堆,根節點的值不小于子節點的堆稱為大根堆。如圖左為小根堆,圖右為大根堆。
Python中 heapq 模塊
Python 中給出了小根堆的輔助實現庫函數 heapq 模塊(其中q表示隊列,方便記憶),大根堆可以通過將數值取反來實現。heapq 模塊只是維護堆結構的操作函數,因此要用列表 list 來表示堆結構本身。
from heapq import * # 使用前首先導入heapq模塊heap = [3, 5, 1, 7, 8, 9, 0, 2, 4, 6]heapq.heapify(heap) # 讓列表 heap具有堆屬性print(heap) # [0, 2, 1, 4, 6, 9, 3, 7, 5, 8] heap[0]值為堆最小值heappush(heap, -1) # 向堆中添加元素,也可以用于創建堆print(heap) # [-1, 0, 1, 4, 2, 9, 3, 7, 5, 8, 6] heap[0]依舊為最小值min_value = heappop(heap) # 彈出堆中最小值print(heap, min_value) # [0, 2, 1, 4, 6, 9, 3, 7, 5, 8] -1min_value = heapreplace(heap, 4) # 彈出堆中最小值,并將值4加入堆中并維持堆結構。print(heap, min_value) # [1, 2, 3, 4, 6, 9, 4, 7, 5, 8] 0nList = nlargest(3, heap) # 返回 heap中前3大的元素print(nList) # [9, 8, 7]nList = nsmallest(3, heap) # 返回 heap中最小的3個元素print(nList) # [1, 2, 3]small_num = heappushpop(heap, -2) # 將數值-2壓入堆 heap中,并返回彈出堆的最小值print(heap, small_num) # [1, 2, 3, 4, 6, 9, 4, 7, 5, 8] -2總結:
| heapify(heap) | 以線性時間將一個列表 heap 轉化為堆 |
| heappush(heap, num) | 將元素 num 壓入堆 heap 中 |
| heappop(heap) | 從對 heap 中彈出最小元素,并返回 |
| heap[0] | 查看堆 heap 中最小值,不彈出 |
| heapreplace(heap, num) | 彈出并返回最小值后,將 num 壓入堆中并維持堆結構,比先調用 heappop(), 再調用heappush() 效率高 |
| nlargest(n, heap) | 返回堆 heap 中 n 個最大元素 |
| nsmallest(n, heap) | 返回堆 heap 中 n 個最小元素 |
| heappushpop(heap, num) | 將值 num 插入到堆 heap 中后,再返回并彈出最小值。和先調用 heappush(), 再調用 heappop() 相比效率更高 |
為 nlargest() 和 nsmallest() 函數指定 key 值進行比較。兩個函數共有三個參數,原型為:nlargest(n , iterbale, key=None) 和 nsmallest(n , iterbale, key=None)。key 值表示用列表元素的某個屬性和函數作為關鍵字進行判斷。
L = [('a', 1), ('b', 2), ('c', 3), ('d', 0)] nList = nlargest(2, L, key = lambda x:x[1]) # key=lambda x:x[1] 表示以前面對象中第二維數據進行排列,更一般的形式為:key=lambda 變量:變量[維數] print(nList) # [('c', 3), ('b', 2)]利用堆結構快速訪問數據流中中位數
對應LeetCode295題:https://leetcode-cn.com/problems/find-median-from-data-stream/
題目描述:如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那么中位數就是所有數值排序之后位于中間的數值。如果從數據流中讀出偶數個數值,那么中位數就是所有數值排序之后中間兩個數的平均值。
代碼實現:
原創不易,如果感覺有所幫助,請點贊支持!感謝!
總結
以上是生活随笔為你收集整理的Python中的堆实现:heapq 模块——利用堆结构实现快速访问数据流中的中位数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: recv、recvfrom[通俗易懂]
- 下一篇: websocket python爬虫_p