デフォルトのheapqは最小キュー実装であり、最大キューのオプションがあるかどうか疑問に思っていますか?ありがとう。
最大ヒープに_heapify_maxを使用してソリューションを試しましたが、プッシュ/ポップ要素を動的に処理する方法は? _heapify_maxは初期化時にのみ使用できるようです。
import heapq
def heapsort(iterable):
h = []
for value in iterable:
heapq.heappush(h, value)
return [heapq.heappop(h) for i in range(len(h))]
if __name__ == "__main__":
print heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
編集、試された_heapify_maxは、動的にプッシュ/ポップ要素に対して機能していないようです。私は両方の方法の出力を同じにしてみましたが、両方の出力は[0、1、2、3、4、5、6、7、8、9]です。
def heapsort(iterable):
h = []
for value in iterable:
heapq.heappush(h, value)
return [heapq.heappop(h) for i in range(len(h))]
def heapsort2(iterable):
h = []
heapq._heapify_max(h)
for value in iterable:
heapq.heappush(h, value)
return [heapq.heappop(h) for i in range(len(h))]
if __name__ == "__main__":
print heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
print heapsort2([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
事前に感謝、リン
過去に、私は単に sortedcontainers のSortedList
を次のように使用しました。
> a = SortedList()
> a.add(3)
> a.add(2)
> a.add(1)
> a.pop()
3
ヒープではありませんが、高速で、必要に応じて直接機能します。
ヒープにする必要がある場合は、一般的な否定クラスを作成してアイテムを保持できます。
class Neg():
def __init__(self, x):
self.x = x
def __cmp__(self, other):
return -cmp(self.x, other.x)
def maxheappush(heap, item):
heapq.heappush(heap, Neg(item))
def maxheappop(heap):
return heapq.heappop(heap).x
しかし、それはもう少しメモリを使用します。
最新のcpythonソースには、役に立つかもしれない _ heappop_max 関数があります:
def _heappop_max(heap):
"""Maxheap version of a heappop."""
lastelt = heap.pop() # raises appropriate IndexError if heap is empty
if heap:
returnitem = heap[0]
heap[0] = lastelt
heapq._siftup_max(heap, 0)
return returnitem
return lastelt
heapq._siftdown_max
を使用してheappush
ロジックを変更すると、目的の出力が得られます。
def _heappush_max(heap, item):
heap.append(item)
heapq._siftdown_max(heap, 0, len(heap)-1)
def _heappop_max(heap):
"""Maxheap version of a heappop."""
lastelt = heap.pop() # raises appropriate IndexError if heap is empty
if heap:
returnitem = heap[0]
heap[0] = lastelt
heapq._siftup_max(heap, 0)
return returnitem
return lastelt
def heapsort2(iterable):
h = []
heapq._heapify_max(h)
for value in iterable:
_heappush_max(h, value)
return [_heappop_max(h) for i in range(len(h))]
出力:
In [14]: heapsort2([1,3,6,2,7,9,0,4,5,8])
Out[14]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [15]: heapsort2([7, 8, 9, 6, 4, 2, 3, 5, 1, 0])
Out[15]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [16]: heapsort2([19,13,15,17,11,10,14,20,18])
Out[16]: [20, 19, 18, 17, 15, 14, 13, 11, 10]
In [17]: heapsort2(["foo","bar","foobar","baz"])
Out[17]: ['foobar', 'foo', 'baz', 'bar']