next up previous contents
Next: Amortisierte Kostenanalyse für Fibonacci-Heaps Up: Fibonacci-Heaps Previous: Fibonacci-Heaps

Die Datenstruktur

Bemerkung: Die doppelte Verkettung der Kinder- bzw. Wurzellisten innerhalb von Heaps erlaubt das Löschen eines Listeneintrages in Zeit $\mathcal{O}(1)$.

Binomial-Queue vs. Fibonacci-Heap:

Überblick:

Operationen worst case amortisiert
Insert $\mathcal{O}(1)$ $\mathcal{O}(1)$
Merge $\mathcal{O}(1)$ $\mathcal{O}(1)$
FindMin $\mathcal{O}(1)$ $\mathcal{O}(1)$
DecreaseKey $\mathcal{O}(\log{n})$ $\mathcal{O}(1)$
Delete $\mathcal{O}(\log{n})$ $\mathcal{O}(\log{n})$
DeleteMin $\mathcal{O}(n)$ $\mathcal{O}(\log{n})$


Linken von Bäumen: Zwei Bäume desselben Wurzel-Rangs werden unter Einhaltung der Heap-Bedingung verbunden. Sind k1 und k2 die Wurzeln der zwei zu linkenden Bäume, so wird ein neuer Baum aufgebaut, dessen Wurzel bzgl. der Schlüssel das Minimum von k1 und k2 ist. Sei dies k2, dann erhält der Baum mit Wurzel k2 als zusätzlichen Unterbaum den Baum mit Wurzel k1, d.h. der Rang von k2 erhöht sich um eins.


\begin{picture}
(115,27)
 \put(10,13){\circle*{2}}
 \put(10,13){\line(1,-1){10}}...
 ... \put(101,22){\makebox(0,0){$k_{2}$}} 
 \put(80,10){\line(3,1){25}}\end{picture}

Dies ist gerade der konstruktive Schritt beim Aufbau von Binomialbäumen. Zur Verbesserung der amortisierten Zeitschranken sind zusätzlich folgende Regel Formuliert:

Kaskadiertes Abschneiden: Algorithmus:


x verliert Kind; y= P(x) : (Vater von x) while (y markiert) do entferne y; füge y unmarkiert in die Liste ein; if (P(y)=NIL) then exit fi y= P(y); od markiere y;

Operationen:
1.
Insert(x) : Füge B (mit dem Element x) in die Wurzelliste ein.
Update Min-Pointer.

\fbox {Kosten $\mathcal{O}(1)$}
2.
Merge() : Verbinde beide Listen und aktualisiere den Min-Pointer.

\fbox {Kosten $\mathcal{O}(1)$}
3.
FindMin() : Es wird das Element ausgegeben, auf das der Min-Pointer zeigt. Dabei handelt es sich sicher um eine Wurzel.

\fbox {Kosten $\mathcal{O}(1)$}
4.
Delete(x)

i)
Falls x Min-Wurzel, DeleteMin -Operator benutzen
ii)
Sonst:


while true do füge Liste der Kinder in die Wurzelliste ein; lösche x, x=Vater(x); if Markierung(x)=0 then Markierung(x)=1 exit else hänge x samt Unterbaum in Wurzelliste; entferne Markierung von x da x Wurzel; x = Vater(x); fi od

5.
DeleteMin() : Diese Operation hat auch Aufräumfunktion und ist daher recht kostspielig. Sei x der Knoten, auf den der Min-Pointer zeigt:


$x:= \uparrow$ Min-Pointer; entferne x aus der Liste; Konkataniere Kinderliste vom x mit der Wurzelliste; while ($\exists \geq 2 $ Bäume von selben Wurzel-Rang i) do erzeuge Baum vom Wurzel-Rang i+1; od update Min-Pointer;

Man beachte, daß an jedem Knoten, insbesondere jeder Wurzel, der Rang gespeichert ist. Zwar vereinfacht dies die Implementierung, doch müssen noch immer Paare von Wurzeln gleichen Rangs gefunden werden. Dies wird wie folgt realisiert: Wir verwenden ein array, dessen Indizies je für einen Rang stehen. Die Elemente sind Zeiger auf eine Wurzel dieses Rangs. Es ist garantiert, daß ein Element nur dann unbesetzt ist, wenn tatsächlich keine Wurzel entsprechenden Rangs existiert. Nach dem Entfernen des Knoten x aus der Wurzelliste fügen wir die Kinder eines nach dem anderen in die Wurzelliste ein und aktualisiern in jedem Schritt das array. Soll eine bereits besetzte Position des arrays beschrieben werden, so wird ein Link-Schritt ausgeführt und versucht, einen Pointer auf die neue Wurzel in die nächsthöhere Position im array zu schreiben. Dies zieht evtl. weitere Link-Schritte nach sich. Nach Abschluß dieser Operation enthält die Fibonacci-Heap nur verschiedene Bäume. Liegt der kanonische Fall vor, daß ausschließlich Binomialbäume im Spiel sind, so erhalten wir durch DeleteMin -Operation eine Binomial-Queue.

\fbox {Zeitkomplexit\uml {a}t f\uml {u}r 
 \textsl{\textsf{DeleteMin}}
: $\mathcal{O}($max Rang + $\char93 $\space Link-Schritte)}

6.
DecreaseKey($K,\Delta$) :


entferne x; y=P(x); füge x unmittelbar in die Wurzelliste ein; Key(x) := Key(x) - $\Delta$;while (y markiert) do entferne y; füge y unmarkiert in die Wurzelliste ein; if (P(y)=NILL) then exit fi y=P(y); od markiere y;

\fbox {Zeitkomplexit\uml {a}t: $\mathcal{O}($max H\uml {o}he)}
Bemerkung: Wird mit einem leeren oder gar keinem Fibonacci-Heap gestartet, und werden ausschließlich die aufbauenden Operationen Insert , Merge und FindMin angewendet, so können nur Binomialbäume enstehen. In diesem natürlichen Fall also liegt stets ein Binomialwald vor, der jedoch i.a. nicht aufgeräumt ist. Das heißt, es existieren mehrere Binomialbäume Bi desselben Typs, die nicht paarweise zu Bi+1-Bäumen verschmolzen sind. Dies geschieht erst bei der Operation DeleteMin . Man beachte, daß nur nach einer solchen Operation momentan ein Binomial Heap vorliegt, ansonsten nur ein Binomialwald.


next up previous contents
Next: Amortisierte Kostenanalyse für Fibonacci-Heaps Up: Fibonacci-Heaps Previous: Fibonacci-Heaps
Abbas-Bardia Kabiri-Jarghouyeh
3/3/1999