Sen oldukça kolay bir yığından i-inci elemanı kaldırabilirsiniz:
h[i] = h[-1]
h.pop()
heapq.heapify(h)
Sadece yığın yeniden heapify son eleman ile kaldırmak ve daha sonra son öğe kaldırmak istediğiniz öğeyi değiştirin. O (n), eğer isterseniz O (log (n)) 'de de aynı şeyi yapabilirsiniz, ancak birkaç tane dahili heapify işlevini çağırmanız gerekir veya larsların işaret ettiği gibi daha iyi kendi koduna heapq.py dışına _siftup/_siftdown:
h[i] = h[-1]
h.pop()
if i < len(h):
heapq._siftup(h, i)
heapq._siftdown(h, 0, i)
Not her durumda sadece o kadar h[i] = h.pop()
eğer i
referanslar son öğe başarısız olur yapamam. Eğer özel bir durumda son elemanı kaldıramazsanız üzerine yazmayı ve pop'i birleştirebilirsiniz.
Not Yığınınızda tipik boyutuna bağlı olarak bu teorik olarak daha az verimli _siftup
/_siftdown
yeniden kullanarak daha hızlı olabilir çıkarırken sadece heapify
arayarak bulabileceği: içgözlem biraz heapify
muhtemelen C uygulandığını ortaya çıkaracaktır ancak iç fonksiyonların C uygulaması ortaya çıkmaz. Performans sizin için önemliyse, hangisinin en iyi olduğunu görmek için tipik veriler üzerinde bazı zamanlama testleri yapmayı düşünün. Büyük kütlelere sahip olmadığınız sürece büyük-O en önemli faktör olmayabilir.
Düzenleme:
_siftdown gerekli değildir: birisi o bir yorum ile _siftdown
çağrısını kaldırmak için bu cevabı düzenlemek için çalıştı. Yeni h [i], eski h [i] 'nin en küçüğüydü, ki bu da hala eski h [i]' nin ebeveyni (yeni h [i] 'nin ebeveyni)' den daha büyüktür. _siftdown bir op-op olacaktır. Henüz henüz bir yorum eklemek için yeterli temsilciniz olmadığından düzenlemeliyim. bu açıklamada kaçırdığınızı ne
h[-1]
hiç h[i]
bir çocuk olma ihtimalidir. h[i]
'a eklenen yeni değer, yığının tamamen farklı bir dalından gelebilir, bu nedenle her iki yönde de elenmiş olması gerekebilir. Sadece yığın geri sort()
kullanmayın neden soran yorumuna da
: _siftup
ve _siftdown
arayarak hem Ey heapify çağırarak, işlemleri (n log) olan O (n) 'dir.sort()
çağrısı, bir O (n log n) işlemidir. Çağırma türünün yeterince hızlı olması mümkündür, ancak büyük yığınlar için gereksiz bir ek yüktür. @Seth Bruder tarafından işaret edilen sorundan kaçınmak için. i
son öğeye başvurduğunda, _siftup()
çağrısı başarısız olur, ancak bu durumda öbekten bir ögeyi haşatlamak, yığın değişmezini bozmaz.
+1, “_siftup” tanımının @AlexMartelli tarafından önerilen programa kopyalanmasının daha temiz olacağını not ederek, [burada] (http://stackoverflow.com/questions/1465662/how-can- i uygulamaya geçirilen bir azalma-anahtarı-özelliğe-içinde-piton-heapq). –
Teşekkürler, '_siftup' kesinlikle ilginç görünüyor! Btw., Neden sadece 'pop()' yerine pop (-1) '? –
@EcirHana sadece kafamın tepesindeki varsayılanı hatırlayamadığım için. Ben hallettim. – Duncan