[python3] 堆 优先队列(priorityqueue) heapq模块

前言

python3的heapq模块提供了堆的数据结构(即优先队列)。

索引

一、堆排序
二、基本push pop
三、其他
        1. 返回堆排序
        2. push+pop组合操作
        3.列表连接+堆排序组合操作

heapq方法

一、堆排序

  • heapq.heapify(x)
    此方法能够在线性时间内将列表x转换为堆排序。

ps:此方法只能返回的是小顶堆排序。
python中没有现成的大顶堆,欢迎访问我的另一篇文章了解python大顶堆实现

代码示例
import heapq
h = [1,5,3,8,6,7,0]
heapq.heapify(h)
print(h)

输出

[0, 5, 1, 8, 6, 7, 3]

二、基本push pop

  • heapq.heappush(heap,item):将item的值插入heap中,保持堆的不变性。
  • heapq.heappop(heap):弹出(即删除)并返回heap的最小的元素,保持堆的不变性。
    如果堆为空,则抛出IndexError
import heapq
h = [1,5,3,8,6,7,0]
heapq.heapify(h)
print("原堆排序:" , h)
heapq.heappush(h,10)
print("插入10后的堆排序:" , h)
print("弹出堆顶:",heapq.heappop(h))
print("弹出一次堆顶后的列表",h)

输出

原堆排序: [0, 5, 1, 8, 6, 7, 3]
插入10后的堆排序: [0, 5, 1, 8, 6, 7, 3, 10]
弹出堆顶: 0
弹出一次堆顶后的列表 [1, 5, 3, 8, 6, 7, 10]

三、其他

1. 返回堆排序

  • heapq.nlargest(n,iterable,key = None):返回大顶堆序列
  • heapq.nsmallest(n,iterable,key = None):返回小顶堆序列

此方法会从将iterable中前n大/小的数以列表的形式返回。
n没有默认值。
iterable可以是一个列表或者元组。
PS:调用该函数不会改变原本iterable的排序。

key 指定带有单个参数的 key 函数,用于从每个输入元素中提取比较键。 默认值为 None (此时会直接对元素的值进行比较)。

欢迎阅读我的另一篇文章,深入了解key函数→

代码示例
import heapq
h = [3,4,2,1,7,5,0]
k = 5
a = heapq.nlargest(k,h) # 大顶对
b = heapq.nsmallest(k,h) # 小顶堆
print(a)
print(b)

输出

[7, 5, 4, 3, 2]
[0, 1, 2, 3, 4]

与C++的priority_queue不同,python堆的数据并不直接存储在该结构中,而是存储在list中,而使用一系列heapq方法实现堆操作。

2. push+pop组合操作

  • heapq.heappushpop(heap,item):先把item加入到堆中,再pop
  • heapq.heapreplace(heap,item):先pop,再把item加入到堆中。

使用这两个函数进行组合的pushpop操作,比单独调用heapq.heappushheapq.heappop效率更高。

代码示例
import heapq
h = [1,5,3,8,6,7,0]
heapq.heapify(h)
print("原堆排序:" , h)
print("弹出的堆顶元素:",heapq.heappushpop(h,10))
print("调用heappushpop后的排序:",h)

print("弹出的堆顶元素:",heapq.heapreplace(h,11))
print("调用heapreplace后的排序:",h)

输出

原堆排序: [0, 5, 1, 8, 6, 7, 3]
弹出的堆顶元素: 0
调用heappushpop后的排序: [1, 5, 3, 8, 6, 7, 10]
弹出的堆顶元素: 1
调用heapreplace后的排序: [3, 5, 7, 8, 6, 11, 10]

3.列表连接+堆排序组合操作

  • heapq.merge(*iterables, key=None, reverse=False):将多个小顶堆序列合并。返回合并后的列表迭代器。
    key指定带有单个参数的key函数,用于从每个输入元素中提取比较键。默认值为None
    reverse为一个布尔值,默认为False,如果值为True,可用于合并两个大顶堆序列。
代码示例
import heapq
a = [1,5,3,8,6,7,0]
b = [1,3,4,6,3,4]
heapq.heapify(a)
heapq.heapify(b)
print("排序后的a列表:",a)
print("排序后的b列表:",b)
h = list(heapq.merge(a,b))
print("合并后的序列:",h)

输出

排序后的a列表: [0, 5, 1, 8, 6, 7, 3]
排序后的b列表: [1, 3, 4, 6, 3, 4]
合并后的序列: [0, 1, 3, 4, 5, 1, 6, 3, 4, 8, 6, 7, 3]

参考资料

heapq — 堆队列算法
Python heapq模块


原创不易,感谢大家的支持。

你可能感兴趣的:(python,标准库,python,数据结构)