日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python中的堆实现:heapq 模块——利用堆结构实现快速访问数据流中的中位数

發布時間:2023/12/19 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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/
題目描述:如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那么中位數就是所有數值排序之后位于中間的數值。如果從數據流中讀出偶數個數值,那么中位數就是所有數值排序之后中間兩個數的平均值。
代碼實現:

import heapqclass MedianFinder:def __init__(self):self.smallheap = [] # 初始化一個小根堆self.bigheap = [] # 初始化一個大根堆,通過對元素取反實現def addNum(self, num: int) -> None: # 添加元素操作,使大根堆中元素始終小于小根堆,兩個堆中元素數目差1,或相等if len(self.smallheap) == len(self.bigheap): # 當前數據中含偶數個數據# 將新加入元素取反,加入大根堆中并返回大根堆中最小值并取反,也就是實際元素最大值。然后將這個值壓入小根堆中。heapq.heappush(self.smallheap, -heapq.heappushpop(self.bigheap, -num))else: # 當前數據含奇數個數據# 將新數據壓入小根堆中,并返回最小值后取反壓入最大堆heapq.heappush(self.bigheap, -heapq.heappushpop(self.smallheap, num))def findMedian(self) -> float: # 返回數據的中位數if len(self.smallheap) == len(self.bigheap): # 當含有偶數個數據時,中位數為小根堆最小值和大根堆最大值的平均值return (self.smallheap[0] - self.bigheap[0])/2else: # 當含有奇數個數據時,中位數為小跟堆最小值。return self.smallheap[0]

原創不易,如果感覺有所幫助,請點贊支持!感謝!

總結

以上是生活随笔為你收集整理的Python中的堆实现:heapq 模块——利用堆结构实现快速访问数据流中的中位数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。