web-dev-qa-db-fra.com

comment obtenir le tas max en python

J'utilise le module heapq en python, je trouve que je ne peux que le tas min, même si j'utilise reverse = True

Je reçois toujours le tas le plus haut

from heapq import *

h=[]
merge(h,key=lambda e:e[0],reverse=True)
heappush(h, (200, 1))
heappush(h, (300,2))
heappush(h, (400,3))
print(heappop(h))

J'obtiens toujours le résultat:

(200, 1)

Je veux obtenir un résultat:

(400,3)

comment faire?

qui est le plus petit élément. Je veux faire éclater le plus grand élément?

ps: cela fait partie de la question trouver le max puis diviser en plusieurs éléments puis le remettre dans le tas.

9
user504909

La documentation dit,

Notre méthode pop renvoie le plus petit élément, pas le plus grand (appelé "tas min" dans les manuels scolaires; un "tas max" est plus courant dans les textes en raison de son aptitude au tri sur place).

Donc, vous ne pouvez pas obtenir directement un tas max. Cependant, une façon de l'obtenir indirectement est de pousser le négatif de l'élément sur le tas, puis de reprendre le négatif juste après avoir sauté l'élément. Ainsi, au lieu de heappush(h, (200, 1)), vous exécutez heappush(h, (-200, -1)). Et pour afficher et imprimer l'élément max, exécutez

negmaxitem = heappop(h)
maxitem = (-negmaxitem[0], -negmaxitem[1])
print(maxitem)

Il existe d'autres façons d'obtenir le même effet, selon ce que vous stockez exactement dans le tas.

Notez que d'essayer h[-1] Dans un tas min ne fonctionne pas pour trouver l'élément max - la définition du tas ne garantit pas que l'élément max finira à la fin de la liste. nlargest devrait fonctionner mais a une complexité temporelle de O(log(n)) pour simplement examiner le plus grand élément dans un tas min, ce qui va à l'encontre de l'objectif du tas. Ma façon a la complexité du temps O(1) dans le tas négatif pour examiner le plus grand élément.

9
Rory Daulton

Pourquoi ne pas utiliser un objet PriorityQueue? Vous pouvez stocker (priority,key) tuples. Une solution simple pour créer un tas max serait de faire de priority l'opposé de key:

from Queue import PriorityQueue
pq = PriorityQueue()
for i in range(10): # add 0-9 with priority = -key
    pq.put((-i,i))
print(pq.get()[1]) # 9
2
Niema Moshiri