Een heap is een complete binaire boom waarbij elke ouder voldoet aan de heap-eigenschap - altijd kleiner (min-heap) of altijd groter (max-heap) dan zijn kinderen. "Compleet" betekent dat elk niveau vol is, behalve mogelijk het laatste dat van links naar rechts wordt gevuld.
1 Min-heap
/ \
3 5
/ \
7 4
Omdat de boom compleet is, slaan we hem op in een platte array - geen pointers nodig. Voor index i: linkerkind = 2i + 1, rechterkind = 2i + 2, ouder = (i - 1) // 2.
| Eigenschap | Min-Heap | Max-Heap | |------------|----------|----------| | Wortel | Kleinste element | Grootste element | | Ouder ≤ Kinderen? | ✅ Ja | ❌ Nee (≥) | | Extract geeft | Minimum | Maximum |
Python's heapq is standaard een min-heap. Voor een max-heap negeer je waarden bij insert en negeer je opnieuw bij extract.
Insert - voeg toe aan het einde, dan bubble up (wissel met ouder zolang kleiner):
import heapq
h = [1, 3, 5, 7]
heapq.heappush(h, 2) # h becomes [1, 2, 5, 7, 3]
Extract min - wissel wortel met laatste element, verwijder laatste, dan sift down (wissel met kleinste kind):
smallest = heapq.heappop(h) # returns 1
Beide operaties kosten O(log n) omdat de boomhoogte log n is.
heapq.heapify(arr) zet een lijst om naar een heap in O(n), niet O(n log n). Het werkt bottom-up door elke niet-bladknoop omlaag te ziften. Dit is een van de meest verrassende complexiteitsresultaten in de informatica.
Sign in to join the discussion
Een priority queue geeft je altijd toegang tot het item met de hoogste prioriteit. Heaps zijn de standaardimplementatie omdat zowel insert als extract O(log n) zijn. Gebruik er een wanneer je "geef me het beste item tot nu toe" nodig hebt.
"Vind de K grootste elementen in een ongesorteerde array."
Houd een min-heap van grootte K bij. Voor elk element: push het; als de heap groter wordt dan K, pop het kleinste. Wat overblijft zijn de K grootste.
import heapq
def top_k(nums, k):
return heapq.nlargest(k, nums)
Tijd: O(n log k) - veel beter dan sorteren wanneer k ≪ n.
Je hebt de 5 hoogste scores nodig uit 1 miljoen entries. Welk heap-type en welke grootte?
Push de kop van elke lijst in een min-heap. Pop het kleinste, push dan het volgende element uit diezelfde lijst. Herhaal tot alle lijsten leeg zijn. Tijd: O(N log K) waarbij N het totaal aantal elementen is.
Onderhoud twee heaps: een max-heap voor de onderste helft en een min-heap voor de bovenste helft. Houd hun grootte in balans (maximaal 1 verschil). De mediaan zit altijd bij één of beide wortels.
Lower half (max-heap): [1, 2, 3] ← max = 3
Upper half (min-heap): [4, 5, 6] ← min = 4
Median = (3 + 4) / 2 = 3.5
Bij de twee-heap mediaan-aanpak, waar gaat een nieuw element eerst naartoe?
Heaps blinken uit bij planning: vergaderruimtes (houd de vroegste eindtijd bij), taakplanning met cooldowns, of CPU-taakwachtrijen. Het kernidee: een heap houdt efficiënt bij "wat eindigt het eerst."
| Behoefte | Beste keuze | Waarom | |----------|-------------|--------| | Herhaald min/max extractie | Heap | O(log n) insert + extract | | Statische data, eenmalig sorteren | Gesorteerde array | O(n log n) eenmalig, O(1) toegang | | Bereik-queries + rangorde-statistieken | Gebalanceerde BST | O(log n) voor alles | | Top-K uit een stroom | Heap van grootte K | O(n log k) totaal |
Welke operatie is O(1) in een min-heap?
| Operatie | Tijd | |----------|------| | Insert | O(log n) | | Extract min/max | O(log n) | | Peek min/max | O(1) | | Heapify | O(n) | | Top-K uit n items | O(n log k) |