堆
推荐直接看网页和本页的heapq库:
8.1 堆 - Hello 算法
基于堆更加高效地解决 Top-k 问题,流程
堆化(Heapify),即建堆操作:如何从一个无序数组或不符合堆性质的完全二叉树构建堆
堆化的核心操作是 heapify_down
(下沉) 或 heapify_up
(上浮),这两个都是强调修复和单个元素,通过递归或迭代调整节点位置,最终使整个数据结构满足堆性质。
Top-k 问题
问题:给定一个长度为n的无序数组 nums
,请返回数组中最大的k个元素。
步骤:
- 初始化一个小顶堆,其堆顶元素最小。
- 先将数组的前k个元素依次入堆。
- 从第k个元素开始,若当前元素大于堆顶元素,则将堆顶元素出堆,并将当前元素入堆(最小元素出堆)。
- 遍历完成后,堆中保存的就是最大的k个元素。
复杂度:
n轮入堆和出堆,堆的最大长度为 k,因此时间复杂度为nlogk
python的heapq(堆队列)库
用法:注意,heapq借助原生的数组实现!!而不是heapq()!
Python 的 heapq
模块提供了基于堆的优先队列实现,支持最小堆(Min Heap)操作。以下是 heapq
的核心用法及常见场景示例:
1. 基本操作
1.1 将列表转换为堆(原地修改)
1 | import heapq |
1.2 插入元素(heappush
)
1 | heapq.heappush(data, 0)# 插入元素并维护堆性质,O(log n) |
1.3 弹出最小元素(heappop
)
1 | min_val = heapq.heappop(data)# 弹出并返回最小值,O(log n) |
2. 高级操作
2.1 获取前 N 个最小/最大元素
1 | # 获取前3个最小值(无需修改原列表) |
2.2 合并多个有序堆
1 | heap1 = [1, 3, 5] |
2.3 自定义优先级(元组排序)
1 | tasks = [(2, 'task1'), (1, 'task2'), (3, 'task3')] |
3. 注意事项
最小堆特性:
heapq
仅实现最小堆,如需最大堆,可将数值取反存储(如push -x
,弹出时再取反)。1
2
3
4data = [3, 1, 4]
max_heap = [-x for x in data]
heapq.heapify(max_heap)
max_val = -heapq.heappop(max_heap)# 弹出最大值 4原地修改:
heapify
、heappush
、heappop
直接修改原列表,不返回新列表。时间复杂度:
heapify
: O(n)heappush
/heappop
: O(log n)nsmallest
/nlargest
: O(n log k)(k 为前 N 个元素)
4. 完整示例
1 | import heapq |
总结
heapq
是 Python 中高效的堆实现,适用于:
- 优先队列(按优先级处理任务)
- Top-K 问题(快速获取前 N 个极值)
- 合并有序序列(如多路归并)
通过灵活使用元组和取反技巧,可以覆盖大多数场景需求。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Min的博客!
评论