Binärer Haufen

Ein binärer Haufen ist das geschaffene Verwenden einer Struktur von Daten des Haufens eines binären Baums. Es kann als ein binärer Baum mit zwei zusätzlichen Einschränkungen gesehen werden:

  • Das Gestalt-Eigentum: Der Baum ist ein ganzer binärer Baum; d. h. alle Niveaus des Baums, außer vielleicht dem letzten (am tiefsten) werden völlig gefüllt, und, wenn das letzte Niveau des Baums nicht abgeschlossen ist, werden die Knoten dieses Niveaus vom linken bis Recht gefüllt.
  • Das Haufen-Eigentum: Jeder Knoten ist größer oder gleich jedem seiner Kinder gemäß einem für die Datenstruktur definierten Vergleich-Prädikat.

Haufen mit einem mathematischen "größer oder gleich" der Vergleich-Funktion werden Max-Haufen genannt; diejenigen mit einem mathematischen "weniger als oder gleich der" Vergleich-Funktion werden Minute-Haufen genannt. Minute-Haufen werden häufig verwendet, um Vorzugswarteschlangen durchzuführen.

Da die Einrichtung von Geschwister in einem Haufen durch das Haufen-Eigentum nicht angegeben wird, können zwei Kinder eines einzelnen Knotens frei ausgewechselt werden, wenn das Tun das Gestalt-Eigentum so nicht verletzt (vergleichen Sie sich mit treap).

Der binäre Haufen ist ein spezieller Fall des d-ary Haufens in der d = 2.

Haufen-Operationen

Beide der Einsatz und entfernt Operationen, modifizieren den Haufen, um sich dem Gestalt-Eigentum zuerst anzupassen, indem sie beitragen oder vom Ende des Haufens umziehen. Dann wird das Haufen-Eigentum durch das Überqueren oder unten der Haufen wieder hergestellt. Beide Operationen nehmen O (loggen Sie n) Zeit.

Einsatz

Um ein Element zu einem Haufen hinzuzufügen, müssen wir eine-Haufen-Operation (auch bekannt als Luftblase, das Durchsickern, das Durchrieseln, Tröpfeln, heapify, oder Kaskade-), durch den folgenden dieser Algorithmus durchführen:

  1. Fügen Sie das Element zum untersten Niveau des Haufens hinzu.
  2. Vergleichen Sie das zusätzliche Element mit seinem Elternteil; wenn sie in der richtigen Ordnung sind, anhalten.
  3. Wenn nicht, tauschen Sie das Element mit seinem Elternteil und kehren Sie zum vorherigen Schritt zurück.

Die Zahl von erforderlichen Operationen ist vom Betrag von Niveaus abhängig das neue Element muss sich erheben, um das Haufen-Eigentum zu befriedigen, so hat die Einfügungsoperation eine Zeitkompliziertheit von O (loggen Sie n).

Als ein Beispiel, sagen Sie, dass wir einen Max-Haufen haben

::

und wir wollen die Nummer 15 zum Haufen hinzufügen. Wir legen zuerst die 15 in die durch die X gekennzeichnete Position. Jedoch wird das Haufen-Eigentum verletzt seitdem 15 ist größer als 8, so müssen wir die 15 und die 8 tauschen. Also, wir haben den Haufen, der nach dem ersten Tausch wie folgt aussieht:

::

Jedoch wird das Haufen-Eigentum noch verletzt seitdem 15 ist größer als 11, so müssen wir wieder tauschen:

::

der ein gültiger Max-Haufen ist. Es gibt kein Bedürfnis, die Kinder danach zu überprüfen. Bevor wir 15 auf X gelegt haben, war der Haufen gültig, das Bedeuten 11 ist größer als 5. Wenn 15 größer ist als 11, und 11 größer ist als 5, dann 15 muss größer sein als 5, wegen der transitiven Beziehung.

Löschen

Das Verfahren, für die Wurzel vom Haufen zu löschen (effektiv das maximale Element in einem Max-Haufen oder das minimale Element in einem Minute-Haufen herausziehend) und die Eigenschaften wieder herstellend, wird Unten-Haufen (auch bekannt als Luftblase unten, das Durchsickern unten, das Durchrieseln unten, Tröpfeln unten, heapify-unten, Kaskade-unten und extract-min/max) genannt.

  1. Ersetzen Sie die Wurzel des Haufens mit dem letzten Element auf dem letzten Niveau.
  2. Vergleichen Sie die neue Wurzel mit seinen Kindern; wenn sie in der richtigen Ordnung sind, anhalten.
  3. Wenn nicht, tauschen Sie das Element mit einem seiner Kinder und kehren Sie zum vorherigen Schritt zurück. (Tausch mit seinem kleineren Kind in einem Minute-Haufen und seinem größeren Kind in einem Max-Haufen.)

Also, wenn wir denselben Max-Haufen wie zuvor haben, entfernen wir die 11 und ersetzen ihn durch die 4.

::

Jetzt wird das Haufen-Eigentum verletzt seitdem 8 ist größer als 4. In diesem Fall ist das Tauschen der zwei Elemente, 4 und 8, genug, um das Haufen-Eigentum wieder herzustellen, und wir brauchen Elemente weiter nicht zu tauschen:

::

Der nach unten bewegende Knoten wird mit den größeren von seinen Kindern in einem Max-Haufen getauscht (in einem Minute-Haufen er würde mit seinem kleineren Kind getauscht), bis er das Haufen-Eigentum in seiner neuen Position befriedigt. Diese Funktionalität wird durch die Funktion von Max-Heapify, wie definiert, unten im Pseudocode für einen ordne-unterstützten Haufen A erreicht. Bemerken Sie, dass "A" mit einem Inhaltsverzeichnis versehen wird, an 1, nicht 0 anfangend, wie auf vielen Programmiersprachen üblich ist.

Für den folgenden Algorithmus zu richtig re-heapify die Reihe muss der Knoten am Index i und seinen zwei direkten Kindern das Haufen-Eigentum verletzen. Wenn sie nicht tun, wird der Algorithmus ohne Änderung zur Reihe misslingen.

Max-Heapify (A, i):

verlassener  2i

Recht  2i + 1

größter  i

wenn verlassen,  heap_length und [link]> [am größten] dann:

größter  hat verlassen

wenn Recht  heap_length und [Recht]> [am größten] dann:

größtes  Recht

wenn größt,  i dann:

tauschen Sie [ich]  Ein [größter]

Max-Heapify (A, am größten)

Die Unten-Haufen-Operation (ohne den vorhergehenden Tausch) kann auch verwendet werden, um den Wert der Wurzel zu modifizieren, selbst wenn ein Element nicht gelöscht wird.

Gebäude eines Haufens

Ein Haufen konnte durch aufeinander folgende Einfügungen gebaut werden. Diese Annäherung verlangt Zeit, weil jede Einfügung Zeit in Anspruch nimmt und es Elemente gibt. Jedoch ist das nicht die optimale Methode. Die optimalen Methode-Anfänge durch das willkürliche Stellen der Elemente auf einen binären Baum, das Respektieren des Gestalt-Eigentums (konnte der Baum durch eine Reihe vertreten werden, sehen unten). Dann vom Tiefststand anfangend und sich aufwärts bewegend, wechseln Sie die Wurzel jedes Subbaums nach unten als im Auswischen-Algorithmus aus, bis das Haufen-Eigentum wieder hergestellt wird. Mehr spezifisch, wenn alle Subbäume, die an etwas Höhe (gemessen vom Boden) anfangen, bereits "heapified" gewesen sind, können die Bäume an der Höhe heapified durch das Senden ihrer Wurzel unten entlang dem Pfad von maximalen geschätzten Kindern sein, wenn sie einen Max-Haufen oder minimale geschätzte Kinder bauen, wenn sie einen Minute-Haufen bauen. Dieser Prozess nimmt Operationen (Tausch) pro Knoten. In dieser Methode finden die meisten heapification in den niedrigeren Ebenen statt. Die Zahl von Knoten an der Höhe ist. Deshalb sind die Kosten von heapifying alle Subbäume:

:

\begin {richten }\aus

\sum_ {h=0} ^ {\\lceil \lg n \rceil} \frac {n} {2^ {h+1}} O (h) & =

O\left (n\sum_ {h=0} ^ {\\lceil \lg n \rceil} \frac {h} {2^h }\\Recht) \\

& \le O\left (n\sum_ {h=0} ^ {\\infty} \frac {h} {2^h }\\Recht) \\

& = O (n)

\end {richten }\aus

</Mathematik>

Das verwendet die Tatsache, dass die gegebene unendliche Reihe h / 2 zu 2 zusammenläuft.

Die Build-Max-Heap-Funktion, die folgt, wandelt eine Reihe um, der einen ganzen versorgt

binärer Baum mit n Knoten zu einem Max-Haufen durch das wiederholte Verwenden von Max-Heapify in von unten nach oben Weise.

Es basiert auf der Beobachtung dass die durch mit einem Inhaltsverzeichnis versehenen Reihe-Elemente

Fußboden (n/2) + 1, Fußboden (n/2) + 2..., n

sind alles reist nach dem Baum ab, so ist jeder ein Ein-Element-Haufen. Build-Max-Heap führt

Max-Heapify auf jedem der restlichen Baumknoten.

Build-Max-Heap (A):

heap_length [Eine]  Länge [Ein]

weil ich  Fußboden (Länge [Ein]/2) downto 1 tue

Max-Heapify (A, ich)

Haufen-Durchführung

Haufen werden mit einer Reihe allgemein durchgeführt. Jeder binäre Baum kann in einer Reihe versorgt werden, aber weil ein Haufen immer ein fast ganzer binärer Baum ist, kann es kompakt versorgt werden. Kein Raum ist für Zeigestöcke erforderlich; statt dessen können der Elternteil und die Kinder jedes Knotens durch die Arithmetik auf Reihe-Indizes gefunden werden. Diese Eigenschaften machen diese Haufen-Durchführung ein einfaches Beispiel einer impliziten Datenstruktur oder Liste von Ahnentafel. Details hängen von der Wurzelposition ab, die der Reihe nach von Einschränkungen einer Programmiersprache abhängen kann, die für die Durchführung oder Programmierer-Vorliebe verwendet ist. Spezifisch manchmal wird die Wurzel am Index 1 gelegt, Raum vergeudend, um Arithmetik zu vereinfachen.

Lassen Sie n die Zahl der Elemente im Haufen und mir sein, ein willkürlicher gültiger Index der Reihe sein, die den Haufen versorgt. Wenn die Baumwurzel am Index 0, mit gültigen Indizes 0 durch n-1 ist, dann hat jedes Element [ich]

  • Kinder [2i+1] und [2i+2]
  • Elternteilafloor ((i&minus;1)/2)]

Wechselweise, wenn die Baumwurzel am Index 1, mit gültigen Indizes 1 durch n ist, dann hat jedes Element [ich]

  • Kinder [2i] und [2i+1]
  • Elternteil [Fußboden (i/2)].

Diese Durchführung wird im heapsort Algorithmus verwendet, wo es dem Raum in der Eingangsreihe erlaubt, wiederverwendet zu werden, um den Haufen zu versorgen (d. h. der Algorithmus im Platz getan wird). Die Durchführung ist auch für den Gebrauch als eine Vorzugswarteschlange nützlich, wo der Gebrauch einer dynamischen Reihe Einfügung einer unbegrenzten Zahl von Sachen erlaubt.

Die upheap/downheap Operationen können dann in Bezug auf eine Reihe wie folgt festgesetzt werden: Nehmen Sie an, dass das Haufen-Eigentum für die Indizes b, b+1..., e hält. Die Funktion des Durchrieselns unten erweitert das Haufen-Eigentum zu b1, b, b+1..., e.

Nur Index i = b1 kann das Haufen-Eigentum verletzen.

Lassen Sie j der Index des größten Kindes von [mir] (für einen Max-Haufen oder das kleinste Kind für einen Minute-Haufen) innerhalb der Reihe b..., e sein.

(Wenn kein solcher Index besteht, weil 2i> e dann das Haufen-Eigentum für die kürzlich verlängerte Reihe hält und nichts getan werden muss.)

Indem

ich die Werte [ich] und [j] das Haufen-Eigentum für die Position tausche, werde ich gegründet.

An diesem Punkt besteht das einzige Problem darin, dass das Haufen-Eigentum für den Index j nicht halten könnte.

Die Funktion des Durchrieselns unten ist angewandter Schwanz rekursiv zum Index j, bis das Haufen-Eigentum für alle Elemente gegründet wird.

Die Funktion des Durchrieselns unten ist schnell. In jedem Schritt braucht man nur zwei Vergleiche und einen Tausch. Der Index-Wert, wo es arbeitet, verdoppelt sich in jeder Wiederholung, so dass am grössten Teil des Klotzes e Schritte erforderlich sind.

Für große Haufen und das Verwenden virtuellen Gedächtnisses, Elemente in einer Reihe gemäß dem obengenannten Schema versorgend, ist ineffizient: (Fast) jedes Niveau ist in einer verschiedenen Seite. B-Haufen sind binäre Haufen, die Subbäume in einer einzelnen Seite behalten, die Anzahl von Seiten vermindernd, die durch bis zu einem Faktor zehn zugegriffen sind.

Die Operation, zwei binäre Haufen zu verschmelzen, nimmt Θ (n) für gleich-große Haufen. Das Bestes, das Sie tun können, ist (im Falle der Reihe-Durchführung) einfach das Verketten der zwei Haufen-Reihe, und bauen Sie einen Haufen des Ergebnisses. Wenn das Mischen eine allgemeine Aufgabe ist, wird eine verschiedene Haufen-Durchführung wie binomische Haufen empfohlen, die mit O verschmolzen werden können (loggen Sie n).

Zusätzlich kann ein binärer Haufen mit einer traditionellen binären Baumdatenstruktur durchgeführt werden, aber es gibt ein Problem mit der Entdeckung des angrenzenden Elements auf dem letzten Niveau auf dem binären Haufen, wenn es ein Element hinzufügt. Dieses Element kann algorithmisch oder durch das Hinzufügen von Extradaten zu den Knoten, genannt "das Einfädeln" des Baums bestimmt werden — anstatt Verweisungen auf die Kinder bloß zu versorgen, wir versorgen den inorder Nachfolger des Knotens ebenso.

Es ist möglich, die Haufen-Struktur zu modifizieren, um Förderung sowohl des kleinsten als auch größten Elements rechtzeitig zu erlauben. Um das zu tun, wechseln die Reihen zwischen Minute-Haufen und max Haufen ab. Die Algorithmen sind grob dasselbe, aber, in jedem Schritt, muss man die Wechselreihen mit Wechselvergleichen denken. Die Leistung ist grob dasselbe als ein normaler einzelner Richtungshaufen. Diese Idee kann zu einem min-max-median Haufen verallgemeinert werden.

Abstammung des Index von Kindern in einer Reihe-Durchführung

Diese Abstammung wird zeigen, wie für jeden gegebenen Knoten (Anfänge von der Null) seine Kinder an gefunden würden und.

Mathematischer Beweis

Von der Zahl in der "Haufen Durchführung" Abteilung kann es gesehen werden, dass jeder Knoten seine Kinder nur nach seinen richtigen Geschwister versorgen kann und die Kinder seiner linken Geschwister versorgt worden sind. Diese Tatsache wird für die Abstammung verwendet.

Gesamtzahl von Elementen von der Wurzel bis jedes gegebene Niveau =, wo Anfänge an der Null.

Nehmen Sie an, dass der Knoten am Niveau ist.

Also, die Gesamtzahl von Knoten von der Wurzel bis vorheriges Niveau würde = sein

Gesamtzahl von Knoten, die in der Reihe bis zum Index = versorgt sind (Auch zählend)

,

Also, die Gesamtzahl von Geschwister auf dem verlassenen dessen ist

::::

Folglich, Gesamtzahl von Kindern dieser Geschwister =

Zahl der Elemente an jedem gegebenen Niveau =

Also, Gesamtgeschwister zum Recht auf is: -

::::

Also, der Index des 1. Kindes des Knotens würde be: -

::::

: [Bewiesener]

Intuitiver Beweis

Obwohl die mathematische Annäherung das zweifellos beweist, weist die Einfachheit der resultierenden Gleichung darauf hin, dass es eine einfachere Weise geben sollte, diesen Beschluss zu erreichen.

Dafür sollten zwei Tatsachen bemerkt werden.

  • Kinder für den Knoten werden am allerersten leeren Ablagefach gefunden.
  • Zweit ist, dass alle Knoten vor dem Knoten, direkt bis zur Wurzel, genau zwei Kinder haben werden. Das ist notwendig, um die Gestalt des Haufens aufrechtzuerhalten.

Jetzt, da alle Knoten zwei Kinder haben (laut der zweiten Tatsache), so werden alle von den Kindern genommenen Speicherablagefächer sein. Wir fügen denjenigen seit Anfängen an der Null hinzu. Dann ziehen wir denjenigen ab, da Knoten keine Kinder noch hat.

Das bedeutet, dass alle gefüllten Speicherablagefächer außer einem - der Wurzelknoten verantwortlich gewesen worden sind. Wurzel ist Kind zu niemandem. So schließlich, die Zählung aller gefüllten Speicherablagefächer sind.

Also, durch die Tatsache ein und seit unseren Indexieren-Anfängen an der Null, selbst gibt den Index des ersten Kindes dessen.

Siehe auch

Links


Neue Weltübersetzung der Heiligen Schriften / IMI Galil
Impressum & Datenschutz