该heapq
模块维护 堆不变式 ,这与按排序顺序维护实际列表对象不同。
引用heapq
文档:
堆是二叉树,其每个父节点的值都小于或等于其任何子节点。此实现使用了该阵列heap[k] <= heap[2*k+1]
及heap[k] <= heap[2*k+2]
所有k
,计数从零元素。为了进行比较,不存在的元素被认为是无限的。堆的有趣特性是它的最小元素始终是根heap[0]
。
这意味着查找最小的元素(只需takeheap[0]
)非常有效,这对于优先级队列非常有用。之后,接下来的2个值将大于(或等于)第一个,之后的下一个4将比其“父”节点大,然后接下来的8个更大,依此类推。
您可以在文档的“理论”部分中详细了解数据结构背后的理论。您也可以在MIT OpenCourseWare算法入门课程中观看此讲座,该课程以一般术语解释该算法。
可以非常有效地将堆转换为排序列表:
def heapsort(heap):
return [heapq.heappop(heap) for _ in range(len(heap))]
通过仅从堆中弹出下一个元素。sorted(heap)
但是,使用应该会更快,因为Python排序所使用的TimSort算法将利用堆中已经存在的部分排序。
如果您只对最小值或前几个最小值感兴趣,则可以使用堆n
,尤其是如果您对连续不断地对这些值感兴趣的话;实际上,添加新项目并删除最小的项目确实非常有效,这比每次添加值时都诉诸列表更为有效。