359 votes

Que dois-je utiliser pour une implémentation de max-heap en Python ?

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 ?

15voto

Zhe He Points 314

J'ai implémenté une version max heap de heapq et l'ai soumise à PyPI. (Très légère modification du code CPython du module heapq).

https://pypi.python.org/pypi/heapq_max/

https://github.com/he-zhe/heapq_max

Installation

pip install heapq_max

Utilisation

tl;dr : même chose que le module heapq sauf que l'on ajoute '_max' à toutes les fonctions.

heap_max = []                           # creates an empty heap
heappush_max(heap_max, item)            # pushes a new item on the heap
item = heappop_max(heap_max)            # pops the largest item from the heap
item = heap_max[0]                      # largest item on the heap without popping it
heapify_max(x)                          # transforms list into a heap, in-place, in linear time
item = heapreplace_max(heap_max, item)  # pops and returns largest item, and
                                    # adds new item; the heap size is unchanged

12voto

Yuchen Zhong Points 2600

Il s'agit d'un simple MaxHeap sur la base de heapq . Bien qu'il ne fonctionne qu'avec des valeurs numériques.

import heapq
from typing import List

class MaxHeap:
    def __init__(self):
        self.data = []

    def top(self):
        return -self.data[0]

    def push(self, val):
        heapq.heappush(self.data, -val)

    def pop(self):
        return -heapq.heappop(self.data)

Utilisation :

max_heap = MaxHeap()
max_heap.push(3)
max_heap.push(5)
max_heap.push(1)
print(max_heap.top())  # 5

11voto

Vikas Prasad Points 1258

J'avais également besoin d'utiliser un max-heap, et je traitais des nombres entiers, donc j'ai simplement enveloppé les deux méthodes dont j'avais besoin à partir de heap comme suit :

import heapq

def heappush(heap, item):
    return heapq.heappush(heap, -item)

def heappop(heap):
    return -heapq.heappop(heap)

Et puis j'ai juste remplacé mon heapq.heappush() y heapq.heappop() appels avec heappush() y heappop() respectivement.

5voto

rlotun Points 3995

Si vous insérez des clés qui sont comparables, mais pas de type int, vous pouvez potentiellement remplacer les opérateurs de comparaison sur eux (c'est-à-dire que <= devient > et > devient <=). Sinon, vous pouvez remplacer heapq._siftup dans le module heapq (ce n'est que du code Python, en fin de compte).

11 votes

"c'est juste du code Python" : cela dépend de votre version et installation de Python. Par exemple, mon fichier heapq.py installé contient du code après la ligne 309 ( # If available, use C implementation ) qui fait exactement ce que le commentaire décrit.

4voto

Gaurav Points 136

Extension de la classe int et surcharge Je ne sais pas. est l'un des moyens.

import queue
class MyInt(int):
    def __lt__(self, other):
        return self > other

def main():
    q = queue.PriorityQueue()
    q.put(MyInt(10))
    q.put(MyInt(5))
    q.put(MyInt(1))
    while not q.empty():
        print (q.get())

if __name__ == "__main__":
    main()

Prograide.com

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.

Powered by:

X