Python inclut le module heapq pour les min-heaps, mais j'ai besoin d'un max heap. Que dois-je utiliser pour une implémentation du max-heap en Python ?
C'est aussi la solution standard.
Python inclut le module heapq pour les min-heaps, mais j'ai besoin d'un max heap. Que dois-je utiliser pour une implémentation du max-heap en Python ?
Wow. Je suis étonné que cela n'est pas fourni par heapq
et qu'il n'y a pas de bonne alternative.
Vous pouvez utiliser
import heapq
listForTree = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
heapq.heapify(listForTree) # for a min heap
heapq._heapify_max(listForTree) # for a maxheap!!
Si vous voulez ensuite faire sauter des éléments, utilisez :
heapq.heappop(minheap) # pop from minheap
heapq._heappop_max(maxheap) # pop from maxheap
Il semble qu'il y ait des fonctions non documentées pour max heap : _heapify_max
, _heappushpop_max
, _siftdown_max
y _siftup_max
.
Wow. Je suis étonné qu'il y a IS une telle solution intégrée dans heapq. Mais alors c'est totalement déraisonnable que c'est PAS même légèrement mentionné dans le document officiel ! WTF !
La solution est de nier vos valeurs lorsque vous les stockez dans le tas, ou d'inverser votre comparaison d'objets comme suit :
import heapq
class MaxHeapObj(object):
def __init__(self, val): self.val = val
def __lt__(self, other): return self.val > other.val
def __eq__(self, other): return self.val == other.val
def __str__(self): return str(self.val)
Exemple d'un max-heap :
maxh = []
heapq.heappush(maxh, MaxHeapObj(x))
x = maxh[0].val # fetch max value
x = heapq.heappop(maxh).val # pop max value
Mais vous devez vous rappeler d'envelopper et de désenvelopper vos valeurs, ce qui nécessite de savoir si vous avez affaire à un tas min ou max.
Ajout de classes pour MinHeap
y MaxHeap
peuvent simplifier votre code :
class MinHeap(object):
def __init__(self): self.h = []
def heappush(self, x): heapq.heappush(self.h, x)
def heappop(self): return heapq.heappop(self.h)
def __getitem__(self, i): return self.h[i]
def __len__(self): return len(self.h)
class MaxHeap(MinHeap):
def heappush(self, x): heapq.heappush(self.h, MaxHeapObj(x))
def heappop(self): return heapq.heappop(self.h).val
def __getitem__(self, i): return self.h[i].val
Exemple d'utilisation :
minh = MinHeap()
maxh = MaxHeap()
# add some values
minh.heappush(12)
maxh.heappush(12)
minh.heappush(4)
maxh.heappush(4)
# fetch "top" values
print(minh[0], maxh[0]) # "4 12"
# fetch and remove "top" values
print(minh.heappop(), maxh.heappop()) # "4 12"
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.