Python:修剪heapq堆,因此它只有X个项目

时间:2013-10-07 22:49:31

标签: python

什么是获取堆的前X项的最快方法,因为堆仍然存在?

我认为有一种比通过弹出堆X次重建堆更好的方法。

2 个答案:

答案 0 :(得分:3)

@Ben是正确的,尽管Python的heapq堆是最小堆而不是最大堆:

newheap = [heappop(oldheap) for _ in range(X)]  # removes from oldheap

通常和它一样好。但是,可以更快,尤其是如果X几乎与len(oldheap)一样大,那么请执行此操作:

newheap = sorted(oldheap)[:X]  # doesn't change oldheap

至少在CPython中,sort方法可以利用oldheap中已有的部分顺序,并且比heappop()提取最小的X元素更快地完成整个列表的排序(排序可以总体上需要较少的比较,并且比较是最昂贵的部分)。这种情况的极端是X == len(oldheap)oldheap已经按排序顺序排列。然后排序需要总计X-1次比较,而重复弹出需要按X*log(X)比较的顺序。

答案 1 :(得分:2)

就渐近复杂性而言,这实际上是你能做到的最好的。你知道前面的项目是最大元素,亚军是它的孩子之一。但是根节点的另一个子节点可能只是第100个最大的节点,而另一半节点中的98节点更高。

当然,一旦你取消了X项,你就不需要重新堆积它们 - 它们已经被排序了,因此它们是一个结构良好的二进制堆。