《Python3標準庫》筆記 heapq堆排序演算法

2021-10-08 18:34:43 字數 3457 閱讀 3743

堆的概念

​ 堆(heapq)是乙個樹形資料結構,其中子節點與父節點有一種有序關係。二叉堆(binary heap)可以使用乙個有組織的列表或陣列表示,其中元素n的子元素位於2*n+1和2*n+2(索引從0開始)。這種布局允許原地重新組織堆,從而不必在增加或者刪除元素時重新分配大量記憶體。

​ 最大堆(max-heap)確保父節點大於或等於其兩個子節點。最小堆(min-heap)要求父節點小於或等於其子節點。python的heapq模組實現了乙個最小堆。

堆的建立

import heapq

import math

from io import stringio

data =[19

,9,4

,10,11

]def

show_tree

(tree, total_width=

36, fill=

' ')

:"""pretty-print a tree"""

output = stringio(

) last_row =-1

for i, n in

enumerate

(tree)

:if i:

row =

int(math.floor(math.log(i +1,

2)))

else

: row =

0if row != last_row:

output.write(

'\n'

) columns =

2** row

col_width =

int(math.floor(total_width / columns)

) output.write(

str(n)

.center(col_width, fill)

) last_row = row

print

(output.getvalue())

print

('-'

* total_width)

print()

heap =

print

('random:'

, data)

print()

for n in data:

print

('add :'

.format

(n))

show_tree(heap)

heapq.heapify(data)

print

('heapified:'

)show_tree(data)

​ 如果按照堆順序一次乙個元素地構建列表,那麼結果與構建乙個無序列表再呼叫heapify()是一樣的。

訪問堆的元素

for i in

range(2

):print

('pop :'

.format

(smallest)

) show_tree(data)

​ 如果希望在乙個操作中刪除現有元素並替換為新值,則可以使用heapreplace()

for n in[0

,13]:

smallest = heapq.heapreplace(data, n)

print

('replace with :'

.format

(smallest, n)

) show_tree(data)

​ 通過原地替換元素,這樣可以維持乙個固定大小的堆,如按優先順序排序的作業佇列。

堆的資料極值

heapq還包括兩個檢查可迭代物件(iterable)的函式,可以查詢其中包含最大或最小值的範圍。

import heapq

from heapq_heapdata import data

data =[19

,9,4

,10,11

]print

('all :'

, data)

print

('3 largest :'

, heapq.nlargest(

3, data)

)print

('from sort :'

,list

(reversed

(sorted

(data)[-

3:])

))print

('3 smallest:'

, heapq.nsmallest(

3, data)

)print

('from sort :'

,sorted

(data)[:

3])

​ 只有當n值(n>1)相對小時使用nlargest()nsmallest()才算高效,不過有些情況下這兩個函式會很方便。

高效合併有序序列

​ 對於小資料集,將多個有序序列合併到乙個新序列很容易。

list(sorted(itertools.chain(*data)))

​ 對於較大的資料集,這個技術可能會占用大量記憶體。merge()不是對整個合併後的序列排序,而是使用乙個堆一次乙個元素地生成乙個新序列,利用固定大小的記憶體確定下乙個元素。

import heapq

import random

random.seed(

2016

)data =

for i in

range(4

):new_data =

list

(random.sample(

range(1

,101),

5)) new_data.sort(

)for i, d in

enumerate

(data)

:print

('{}: {}'

.format

(i, d)

)print

('\nmerged:'

)for i in heapq.merge(

*data)

:print

(i, end='')

print

()

​ 由於merge()的實現使用乙個堆,所以它會根據所合併的序列個數消費記憶體,而不是根據這些序列中的元素個數。

Python3標準庫 statistics統計計算

statistics模組實現了很多常用的統計公式,允許使用python的各種數值型別 int float decimal和fraction 來完成高效計算。共支援3種形式的平均值 均值 mean 中值或中位數 median 以及眾數 mode 可以用mean 計算算術平均值。from statist...

Python3標準庫學習 二

這個模組包含 python 中使用的內建函式.一般不用手動匯入這個模組 python會幫你做好一切.python允許你實時地建立函式引數列表.只要把所有的引數放入乙個元組中或者字典中 示例 如下 encoding gb2312 created on 2012 5 1 author administr...

Python3標準庫 calendar處理日期

calendar模組第一了calendar類,其中封裝了一些值的計算,如給定的乙個月或一年中的周日期。另外,textcalendar和htmlcalendar類可以生成經過預格式化的輸出。prmonth 方法是乙個簡單的函式,可以生成月的格式化文字輸出。import calendar c calen...