Menu
Coddy logo textTech

Heap (Binärer Heap)

Zuletzt aktualisiert

Ein binärer Heap ist ein vollständiger Binärbaum, der den kleinsten (Min-Heap) oder größten (Max-Heap) Wert an der Wurzel hält. Diese Visualisierung ist ein Min-Heap: Jeder Elternknoten ist kleiner oder gleich seinen Kindern. Um einen Wert hinzuzufügen, hängt man ihn an die nächste freie Position an und lässt ihn dann "aufsteigen", indem man ihn mit seinem Elternknoten tauscht, solange er kleiner ist, bis die Heap-Eigenschaft wieder erfüllt ist. Drücken Sie oben auf Wiedergabe, um zu sehen, wie jeder neue Wert an seinen Platz aufsteigt.

Da ein Heap ein vollständiger Baum ist, wird er kompakt in einem Array gespeichert: Die Kinder von Knoten i liegen bei 2i+1 und 2i+2. Einfügen und Entfernen des Minimums sind O(log n) (ein Pfad von der Wurzel zu einem Blatt), während das Ablesen des Minimums O(1) ist - genau das, was eine Prioritätswarteschlange braucht.

Zeit- und Speicherkomplexität

OperationKomplexitätHinweise
Min/Max ansehenO(1)Es ist immer die Wurzel
Einfügen (push)O(log n)Entlang eines Pfads aufsteigen
Min/Max entfernenO(log n)Entlang eines Pfads absteigen
Heap aufbauenO(n)Alles auf einmal heapify
SpeicherO(n)Array-basiert, keine Zeiger

Schritt für Schritt (push)

SchrittWas passiert
1Hängen Sie den neuen Wert am Ende an (das nächste freie Blatt).
2Vergleichen Sie ihn mit seinem Elternknoten.
3Ist er kleiner (Min-Heap), tauschen Sie ihn nach oben.
4Wiederholen, bis er nicht mehr kleiner als sein Elternknoten ist oder die Wurzel erreicht.

Durchgerechnetes Beispiel

Aufbau eines Min-Heaps durch Einfügen von [5, 3, 8, 1, 4] Wert für Wert:

PushArray nach dem AufsteigenAktion
5[5]Der erste Wert wird zur Wurzel.
3[3, 5]3 < Elternknoten 5, steigt daher bis zur Wurzel auf.
8[3, 5, 8]8 > Elternknoten 5, bleibt daher ein Blatt.
1[1, 3, 8, 5]1 < Elternknoten 5, Tausch; dann 1 < Elternknoten 3, steigt bis zur Wurzel auf.
4[1, 3, 8, 5, 4]4 > Elternknoten 3, bleibt daher; das Minimum 1 verbleibt an der Wurzel.

Wann man einen Heap verwendet

Verwenden, wennVermeiden, wenn
Sie wiederholt das kleinste oder größte Element aus einer sich ändernden Menge brauchen.Sie beliebige Werte suchen müssen, nicht nur den Extremwert - verwenden Sie einen BST oder ein Hash-Set.
Sie eine Prioritätswarteschlange für Dijkstra, A* oder einen Scheduler implementieren.Sie die Daten jederzeit vollständig sortiert halten müssen.
Sie Einfügen und Entfernen des Minimums in O(log n) mit kompakter Array-Anordnung wollen.Sie ein schnelles Nachschlagen oder Entfernen eines bestimmten (nicht Wurzel-) Elements brauchen.
Sie einen Strom von Elementen zusammenführen und nach Priorität herausziehen müssen.Der Datensatz winzig ist und ein linearer Durchlauf einfacher und schnell genug ist.

Heap (Priority Queue)-Code

Eine saubere, lauffähige Heap (Priority Queue)-Implementierung in Python, JavaScript, Java, C++, C. Wähle eine Sprache, kopiere den Code oder öffne ihn vorgeladen im Coddy-Playground.

Heap (Priority Queue)-Code in Python

Python
1class MinHeap:2    def __init__(self):3        self.data = []4
5    def push(self, value):6        # Append at the end, then bubble up to restore order7        self.data.append(value)8        i = len(self.data) - 19        while i > 0:10            parent = (i - 1) // 211            if self.data[parent] <= self.data[i]:12                break13            self.data[i], self.data[parent] = self.data[parent], self.data[i]14            i = parent15
16    def pop(self):17        # Move the last leaf to the root, then sift it down18        top = self.data[0]19        last = self.data.pop()20        if self.data:21            self.data[0] = last22            self._sift_down(0)23        return top24
25    def _sift_down(self, i):26        n = len(self.data)27        while True:28            smallest = i29            left, right = 2 * i + 1, 2 * i + 230            if left < n and self.data[left] < self.data[smallest]:31                smallest = left32            if right < n and self.data[right] < self.data[smallest]:33                smallest = right34            if smallest == i:35                return36            self.data[i], self.data[smallest] = self.data[smallest], self.data[i]37            i = smallest38
39
40heap = MinHeap()41for value in [5, 3, 8, 1, 9, 2]:42    heap.push(value)43
44print("Heap array:     ", heap.data)45print("Popped in order:", [heap.pop() for _ in range(6)])
Führe diesen Code im Python-Playground aus

Heap-FAQ

Wofür wird ein Heap verwendet?
Heaps implementieren Prioritätswarteschlangen, die Dijkstras Kürzeste-Wege-Algorithmus, Task-Scheduler und Ereignissimulationen antreiben. Sie sind auch der Motor hinter Heapsort. Immer wenn Sie wiederholt das kleinste oder größte Element aus einer sich ändernden Menge brauchen, ist ein Heap das richtige Werkzeug.
Was ist der Unterschied zwischen einem Heap und einem binären Suchbaum?
Beide sind Binärbäume, aber ein BST hält eine vollständige Links-nach-rechts-Sortierung (die eine geordnete Suche ermöglicht), während ein Heap nur die Eltern-Kind-Beziehung garantiert (Min oder Max an der Wurzel). Ein Heap bietet O(1)-Zugriff auf den Extremwert; ein BST bietet O(log n)-Suche für jeden Wert.
Warum wird ein Heap in einem Array gespeichert?
Da ein Heap immer ein vollständiger Binärbaum ist, bilden seine Knoten sich perfekt auf Array-Indizes ab: Die Kinder von Index i liegen bei 2i+1 und 2i+2, der Elternknoten bei (i-1)/2. Das vermeidet das Speichern von Kind-Zeigern und bietet exzellente Cache-Leistung.
Ist ein Heap dasselbe wie ein sortiertes Array?
Nein. Ein Heap garantiert nur, dass jeder Elternknoten kleiner (Min-Heap) oder größer (Max-Heap) als seine Kinder ist, sodass Geschwister und Cousins in keiner bestimmten Reihenfolge stehen. Ein sortiertes Array ist vollständig geordnet, kostet aber O(n) beim Einfügen, während ein Heap in O(log n) einfügt und dennoch sofortigen Zugriff auf den Extremwert bietet.
Wann sollte ich einen Heap verwenden, statt ein Array einfach zu sortieren?
Greifen Sie zu einem Heap, wenn sich die Daten ständig ändern und Sie nur das aktuelle Minimum oder Maximum brauchen - Einfügen und Entnehmen kosten je O(log n), gegenüber dem erneuten Sortieren des gesamten Arrays. Wenn Sie einen statischen Datensatz haben und alle Elemente in Reihenfolge wollen, ist eine einzige O(n log n)-Sortierung einfacher und oft schneller.
Dauert der Aufbau eines Heaps aus n Elementen O(n log n)?
Nicht, wenn Sie ihn auf einmal aufbauen. Das Einfügen von n Elementen nacheinander ist O(n log n), aber das Bottom-up-heapify, das vom letzten Elternknoten bis zur Wurzel absteigt, läuft insgesamt in O(n), weil die meisten Knoten nahe am Boden liegen und nur eine kurze Strecke absteigen.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S