文章目录
- 小根堆的特点
- Python 中的 `heapq` 模块
- 1. `heapq.heappush(heap, item)`
- 2. `heapq.heappop(heap)`
- 3. `heapq.heapify(x)`
- 4. `heapq.heappushpop(heap, item)`
- 5. `heapq.heapreplace(heap, item)`
- 6. `heapq.nsmallest(n, iterable)`
- 7. `heapq.nlargest(n, iterable)`
- 小根堆的应用场景
- 示例:使用小根堆实现优先级队列
- 注意事项
在 Python 中,小根堆(Min Heap)是一种特殊的二叉树数据结构,其中每个父节点的值都小于或等于其子节点的值。堆的根节点(堆顶)是整个堆中的最小元素。Python 提供了内置模块 heapq
来实现堆操作,默认情况下 heapq
实现的是小根堆。
小根堆的特点
- 堆顶元素最小:堆顶元素始终是堆中的最小值。
- 完全二叉树:堆是一棵完全二叉树,通常用数组来实现。
- 高效操作:
- 插入元素的时间复杂度为 (O(\log n))。
- 删除堆顶元素的时间复杂度为 (O(\log n))。
- 获取堆顶元素的时间复杂度为 (O(1))。
Python 中的 heapq
模块
heapq
是 Python 的标准库模块,提供了对小根堆的支持。以下是 heapq
的常用函数:
1. heapq.heappush(heap, item)
- 将元素
item
插入堆heap
中,并保持堆的性质。 - 示例:
python">import heapq heap = [] heapq.heappush(heap, 3) heapq.heappush(heap, 1) heapq.heappush(heap, 2) print(heap) # 输出: [1, 3, 2]
2. heapq.heappop(heap)
- 弹出并返回堆
heap
中的最小元素(堆顶元素),同时保持堆的性质。 - 示例:
python">import heapq heap = [1, 3, 2] print(heapq.heappop(heap)) # 输出: 1 print(heap) # 输出: [2, 3]
3. heapq.heapify(x)
- 将列表
x
原地转换为一个堆,时间复杂度为 (O(n))。 - 示例:
python">import heapq heap = [3, 1, 2] heapq.heapify(heap) print(heap) # 输出: [1, 3, 2]
4. heapq.heappushpop(heap, item)
- 先将元素
item
插入堆中,然后弹出并返回堆中的最小元素。 - 示例:
python">import heapq heap = [1, 3, 2] print(heapq.heappushpop(heap, 0)) # 输出: 0 print(heap) # 输出: [1, 3, 2]
5. heapq.heapreplace(heap, item)
- 先弹出并返回堆中的最小元素,然后将元素
item
插入堆中。 - 示例:
python">import heapq heap = [1, 3, 2] print(heapq.heapreplace(heap, 0)) # 输出: 1 print(heap) # 输出: [0, 3, 2]
6. heapq.nsmallest(n, iterable)
- 返回可迭代对象
iterable
中最小的n
个元素。 - 示例:
python">import heapq data = [3, 1, 4, 1, 5, 9, 2, 6] print(heapq.nsmallest(3, data)) # 输出: [1, 1, 2]
7. heapq.nlargest(n, iterable)
- 返回可迭代对象
iterable
中最大的n
个元素。 - 示例:
python">import heapq data = [3, 1, 4, 1, 5, 9, 2, 6] print(heapq.nlargest(3, data)) # 输出: [9, 6, 5]
小根堆的应用场景
- 优先级队列:小根堆常用于实现优先级队列,堆顶元素始终是优先级最高的元素。
- Top K 问题:例如查找最小的 K 个数或最大的 K 个数。
- Dijkstra 算法:在图的最短路径算法中,小根堆用于高效地找到当前距离最小的节点。
- 合并有序列表:可以使用堆来高效地合并多个有序列表。
示例:使用小根堆实现优先级队列
python">import heapq# 创建一个优先级队列
pq = []
heapq.heappush(pq, (2, "code"))
heapq.heappush(pq, (1, "eat"))
heapq.heappush(pq, (3, "sleep"))# 按优先级顺序处理任务
while pq:priority, task = heapq.heappop(pq)print(f"Processing task: {task} (priority: {priority})")
输出:
Processing task: eat (priority: 1)
Processing task: code (priority: 2)
Processing task: sleep (priority: 3)
注意事项
- 默认是小根堆:
heapq
默认实现的是小根堆。如果需要大根堆,可以通过插入负数来实现。- 示例:
python">import heapq heap = [] heapq.heappush(heap, -3) heapq.heappush(heap, -1) heapq.heappush(heap, -2) print(-heapq.heappop(heap)) # 输出: 3
- 示例:
- 堆的元素可以是元组:
heapq
支持元组作为元素,元组的第一个元素用于比较(优先级)。
通过 heapq
模块,Python 提供了一种简单而高效的方式来实现小根堆,适用于各种需要高效管理最小值的场景。