我正在尝试通过否定列表的所有值来创建最大堆,但是它似乎不起作用:
import heapq
x = range(1,10)
neg = [-n for n in x]
heapq.heappop(neg) # -1
heapq.heappop(neg) # -9
heapq.heappop(neg) # -8
如果可以的话
heapq.heappop(x) # 1
heapq.heappop(x) # 2
heapq.heappop(x) # 3
它似乎正常工作。关于-1为什么返回的任何想法吗?
答案 0 :(得分:2)
除非首先要维护堆不变式,否则不应该使用heappush/heappop
。
要从现有列表创建堆,请使用heapq.heapify(mylist)
。
>>> neg = [-n for n in range(1,10)]
>>> neg[0] # peek
-1
>>> heapq.heapify(neg)
>>> neg[0] # peek
-9
>>> -heapq.heappop(neg) # largest element
9
答案 1 :(得分:0)
heapq.heappop
仅对minheaps为 ;您不能仅仅制作一个maxheap并期望基于minheap的函数能够在其上工作,因为它没有观察到minheap不变式。
如果目标是首先弹出-9,则需要通过(有效地O(n)
)首先对其进行堆化来使堆支持适当的不变式:
heapq.heapify(neg)
之后,您的代码将从-9弹出到-1。
如果您要尝试使用maxheap,则不支持。 All the publically documented heapq
functions work with minheaps(添加了重点):
以下API与教科书堆算法在两个方面有所不同:(a)我们使用基于零的索引。这使得节点的索引与其子节点的索引之间的关系不太明显,但由于Python使用基于零的索引,因此更适合。 (b)我们的pop方法返回的是最小的项目,而不是最大的项目(在教科书中称为“最小堆”;在文本中,“最大堆”由于适用于就地排序而更为常见)。
该模块中有一些基于maxheap的已选择功能(未记录),这些功能可以正常工作,例如heapq._heappop_max
,但它们不是API的文档部分,并且随时可能更改或消失。