目录
heapq 是 python 的一个库,用一个列表来维护一个最小堆。
1、heapq 的常用方法
import heapq
min_heap = [] 创建一个空列表
1、# 向 min_heap 中添加一个数据 val,并按照最小堆的广度优先顺序重新排列
heapq.heappush(min_heap, val)
2、# 返回并删除最小堆 min_heap 的根节点(即最小值),剩余的节点重排为新的最小堆
heapq.heappop(min_heap)
3、# 向堆中加入数据 val,然后返回并删除最小堆 min_heap 的根节点(即最小值)
heapq.heappushpop(min_heap, val)
4、# 把一个列表转换为最小堆
a_list = [val1, val2, ...]
heapq.heapify(a_list)
5、# 从可迭代的迭代器(如列表)中返回最大的n个数,可以指定比较的key
heapq.nlargest(n, iterable[, key])
6、# 从可迭代的迭代器(如列表)中返回最小的n个数,可以指定比较的key
heapq.nsmallest(n, iterable[, key])
2、几个例子
a、最小堆的创建以及增删
heapq 底层是使用列表维护的,因此下面例子中的列表 min_heap 始终是列表类型,向堆中插入数据是一个依数据插入的顺序模拟向最小堆中插入数据的过程,数据在 min_heap 中的排列顺序是按照堆的广度优先顺序排列的。
import heapq
min_heap = []
"""
3
"""
heapq.heappush(min_heap, 3) # 向最小堆中加入元素 3
"""
3
/
8
"""
heapq.heappush(min_heap, 8)
"""
1
/ \
8 3
"""
heapq.heappush(min_heap, 1)
print(min_heap) # [1, 8, 3],按最小堆的广度优先顺序排列
print(heapq.heappop(min_heap)) # 1
print(heapq.heappop(min_heap)) # 3
print(heapq.heappop(min_heap)) # 8
# print(heapq.heappop(min_heap)) # 抛出异常,因为堆已经空了
a_list = [2, 5, 3]
heapq.heapify(a_list) # 将列表转换为最小堆
print(heapq.heappop(a_list)) # 2
print(heapq.heappop(a_list)) # 3
print(heapq.heappop(a_list)) # 5
# print(heapq.heappop(a_list)) # 抛出异常,因为堆已经空了
b、如何使用 heapq 创建最大堆
import heapq
a_list = [2, 5, 3]
a_list = [-e for e in a_list] # 取负数
heapq.heapify(a_list) # 将列表转换为最小堆
print(-heapq.heappop(a_list)) # 5 记得加负号还原数据
print(-heapq.heappop(a_list)) # 3
print(-heapq.heappop(a_list)) # 2
c、获取第 k 大/第 k 小数据
import heapq
a_list = [2, 5, 3, 4]
k = 3
# 返回前 k 个最大数据的列表
k_max = heapq.nlargest(k, a_list)
k_min = heapq.nsmallest(k, a_list)
print(k_max[-1]) # 第 k 大的值
print(k_min[-1]) # 第 k 小的值
d、列表中的元素是元组
当列表中的元素是元组时,此时若创建最小堆,则是按照各元组第一个元素的字典序创建的。
nums = []
a = [(1,2,3), (6,3,4), (2,4,5), (3,5,6)]
"""
1 -> [1]
"""
heapq.heappush(nums, a[0])
"""
1
/ -> [1, 6]
6
"""
heapq.heappush(nums, a[1])
"""
1
/ \ -> [1, 6, 2]
6 2
"""
heapq.heappush(nums, a[2])
"""
1 1
/ \ / \
6 2 --> 3 2 --> [1, 3, 2, 6]
/ /
3 6
"""
heapq.heappush(nums, a[3])
print(nums)
"""
输出结果(相当于是对各元组第一个元素 [1,6,2,3] 做堆转换):
[(1, 2, 3), (3, 5, 6), (2, 4, 5), (6, 3, 4)]
"""