next up previous contents
Next: Fibonacci-Heaps Up: Priority Queues Previous: Priority Queues

Binomial Queues (binomial heaps)

Um binomial Queues betrachten zu können, definieren wir zunächst ihre nichttrivialen Bestandteile: Binomialbäume

Definition: Die Binomialbäume sind rekursive wie folgt definiert:


\begin{picture}
(100,30)
 \put(7.5,20){\circle*{2}}
 \put(7.5,20){\circle{7}}
 \...
 ...t(30,25){\makebox(25,5){B$_2$}}
 \put(55,25){\makebox(45,5){B$_n$}}\end{picture}

Achtung: Binomialbäume sind keine Binärbäume! Wie in folgender Darstellung dieser Bäume deutlich wird, hat Bn an der Wurzel Grad n.
Binomialbäume haben folgende Zerlegungseigenschaften:

Lemma: Ein Bn läßt sich wie folgt zerlegen:
(1)


\begin{picture}
(125,30)
 \put(10,10){\circle*{2}}
 \put(10,10){\line(1,-1){10}}...
 ...er{800}(115,10)(35,30)(35,30)
 \multiput(70,5)(3,0){4}{\circle*{1}}\end{picture}




(2)


\begin{picture}
(100,50)
 \put(0,5){\circle*{2}}
 \put(0,0){\makebox(10,5){B$_0$...
 ...7.5){\makebox(23,5)[r]{R''uckgrat}}
 \put(35,40){\vector(4,-1){20}}\end{picture}

\fbox {\parbox[c]{12.45cm}{\textbf{Satz:}
Es gilt:
 \begin{enumerate}
 \item $B_...
 ...tem $B_n$\space hat $\binom{n}{i}$\space Knoten in Tiefe $i$
 \end{enumerate}}}

Beweis: $\Diamond$

Bemerkung: Eine mögliche Implementierung von Binomialbäumen ist das Schema ``Pointer zu Kind 1. und zum nächsten Geschwister``.
Definition: Eine Binomial Queue mit N Elementen wird wie folgt aufgebaut:
1.
Betrachte die Binärdarstellung bin(N) von N
2.
Für jedes gesetzte Bit (``1``) an Position i wird ein Binomialbaum vom Type Bi benötigt. Dieser hat bekanntlich 2i Knoten
3.
Verbinde die Binomialbäume in einer doppelt verketteten zirkulären
Liste.
4.
Beachte, daß innerhalb jedes Binomialbaums die Minimumsvariante der Heap-Bedingung, nämlich VATER$\leq$SOHN erfüllt sein muß. Dadurch ist die Wurzel eines einzelnen Binomialbaums gleichzeitig sein minimales Element.
5.
Richte einen Min-Pointer auf das Element in der Wurzel-Liste mit minimalem Schlüssel. Es ist dann das kleinste Element von allen in der Binomial Queue
Beachte, daß Priority-Queues wegen $\mathcal{O}(n)$ für Suchen keine Suchstrukturen
sind.

Beispiel: N=11 =(1011)2:


\begin{picture}
(125,65)
\put(47.5,60){\makebox(0,0){$B_3$}}
\put(47.5,52.5){\ci...
 ...
\put(105,30){\vector(-1,1){8}}
\put(105,25){\makebox(10,5){$min$}}\end{picture}

Operationen:
1.
IsElement : Die Heap-Bedingung wirkt sich nur auf die Anordnung der Datenelemente innerhalb jedes einzelnen Binomialbaums aus, regelt aber nicht, in welchem Binomialbaum ein gegebenes Element gespeichert sein muß. Tatsächlich kann ein Element in jedem der vorhandenen Binomialbäume stehen. Das Suchen ist hier nicht effizient implementierbar, denn im worst-case muß jedes Element eines Binomialbaums angeschaut werden. Bi enthält 2i Knoten und eine Binomial Queue mit N Elementen besitzt maximal die Binomialbäume $B_0,B_1,..B_{\log{N}-1}$. Also wären zum Suchen eines Elements schlimmstenfalls $2^0+2^1+ \dots + 2^{\log{N}-1} = N-1 = \mathcal{O}(N)$ Elemente zu betrachten. Daher wird eine gesonderte Datenstruktur, etwa ein Suchbaum, für die IsElement -Operation verwendet. Dort ist Suchen mit Zeitaufwand $\mathcal{O}(\log{n})$ möglich.

2.
Merge : Das Vorgehen für das Merge zweier Vorrangwarteschlangen entspricht genau der Addition zweier Binärzahlen: Ein einzelnes Bi wird übernommen, aus zwei Bis wird ein Bi+1 konstruiert. Damit die Heap-Bedingung erhalten bleibt, wird als Wurzel des entstehenden Binomialbaums Bi+1 die kleinere der Wurzeln der beiden Bi genommen (*). Allerdings kann ein solcher Übertrag dazu führen, daß im nächsten Verschmelzungsschritt drei Bi+1 zu verschmelzen sind. Dann wird unter Beobachtung obiger Regel ein Bi+2 gebildet, und der verbleibende Bi+1 unverändert gelassen.

Algorithmus:


for i:= 0,1,2,3,.. do if $(\exists$ genau 3 Bis) then erzeuge/verbinde Bi+1 nach (*) und behalte ein Bi; elseif $(\exists$ genau 2 Bis) then erzeuge Bi+1 nach (*) ; elsif $(\exists$ ein Bi) then behalte es; fi od

Komplexität: Binomial Queue Nr. 1 mit N1 Elementen hat $\leq \log{N_1}$Binomialbäume, und analog hat Binomial Queue Nr. 2 mit N2 Elementen $\leq \log{N_2}$Binomialbäume. Sei N:=N1+N2. Ein einzelner Merge -Vorgang, das Zusammenhängen zweier Binomialbäume erfolgt in konstanter Zeit. Natürlich muß er so oft ausgeführt werden, wie Binomialbäume in der resultierenden Binomial Queue vorliegen. Diese Anzahl wiederum ist höchstens $\log{N}$.

\fbox {Zeitkomplexit\uml {a}t $\mathcal{O}(\log N) = \mathcal{O}(\log{(N_1+N_2)})$}
3.
Insert : Die Insert -Operation wird einfach durch Merge -Operation implementiert. Die Vorrangswarteschlange, die neu hinzukommt, ist trivial. Sie enthält nur einen Binomialbaum B0.
1     1   1   1
(B7)     (B4)   (B2)   (B0)
              1
1     1   1 1 1
\fbox { Kosten $\mathcal{O}(\log {n})$}
4.
Initialisierung einer Binomial-Queue durch N sukzessive Insert -Operationen:
Kosten mit $\mathcal{O}(n\log{n})$ schlecht abgeschätzt. Dabei möge sowohl das Einfügen dieses neuen einelementigen Baum als auch jede rekursive Verschmelzungsschritt eine Zeiteinheit kosten, denn jede dieser Operationen ist von der Komplexität $\mathcal{O}(1)$. Wir sind an den gesamten Kosten zum Aufbau einer Binomial Queue mit N Elementen interessiert. Dies sind übrigens identisch zum Aufwand für das binäre Hochzählen von 0 bis N, wenn jeder Zählschritt und jeder Übertrag eine Zeiteinheit kosten:
$\underbrace{\underbrace{\underbrace{\underbrace{\underbrace{0+1}_1+1}_{2\text{ Schritte}}+1}_1+1}_3+1}_1$
Sei an die Anzahl der Schritte (Einfügen des neuen Elements und anschließende Verschmelzungen) beim Mergen eines Knotens zu einer Queue mit (n-1) Elementen. Dann gilt für an:
n an
1 2
..4 1 3
..8 1 2 1 4
..16 1 2 1 3 1 2 1 5
..32 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 6
Man erkennt sofort, daß die h-te Zeile von der Länge 2k ist, und alle Elemente der Zeilen 1,2,..,(k-1) enthält, wobei das letzte Element um eins erhöht ist. Daraus ergeben sich folgende Rekursionsgleichungen für an:

\begin{displaymath}
\begin{split}
 a_1 & = 1 \\  a_n & = a_{\frac{n}{2}} +1 \tex...
 ...= a_{n-2^{\lfloor \log{n} \rfloor}} \text{ sonst}\\ \end{split}\end{displaymath}

Diese Bestimmungsgleichung ist unmittelbar einsichtig, denn für $n\in 2^{\mathbbm{N}_0}$ unterscheidet sich die Situation von n=2i Knoten nur insofern von der Situation mit $\frac{n}{2} = 2^{i-1}$Knoten, daß im ersten Fall noch ein Binomialbaum Bi-1 vorliegt. Das Hinzunehmen eines weiteren Knotens löst in beiden Fällen die selbe Folge von Verschmelzungsschritten aus, mit der Einschränkung, daß im letzteren Fall der neu entstandenen Baum Bi-1 mit dem vorhandenen zu einem Bi vereinigt wird. Das ist die ``+1`` in $a_n = a_\frac{n}{2} +1$. Im Falle $n\not\in
2^{\mathbbm{N}_0}$ liegen ähnliche Verhältnisse vor. Zwei Queues mit n bzw. ($n-2^{\lfloor \log{n}
\rfloor}$) Knoten unterscheiden sich nur um einen Baum $B_{\lfloor \log{n} \rfloor}$. Gesucht ist nun $S_n := \Sigma_{k=1}^n a_k$. Statt obige Rekursionsgleichungen zu expandieren und eine explizite Darstellung für an zu suchen, die dann aufsummiert wird, betrachten wir einfach S2k. Obiger Tabelle sieht man an, daß S2k=S2k-1+1 gilt. Substituiert man S2k durch Tk und löst man die entstehene Rekursionsgleichung Tk = 2Tk-1+1, so ergibt sich Tk = 2k+1-1, also Sn= 2n-1. Folglich ist:
\fbox {$S_N = \mathcal{O}(N)$}
5.
FindMin : Diese Operation ist trivial ausführbar, denn es ist ein Pointer auf das minimale Element gegeben. Daher ist auch die Zeitkomplexität $\mathcal{O}(1)$.
6.
DeleteMin :Das Minimum ist auf Grund der Heapbedingung Wurzel eines Binomialbaums Bk in der Liste. Wird es gelöscht, so zerfällt der Binomialbaum in k Teilbäume $B_0,B_1,\dots,B_{k-1}$


\begin{picture}
(105,50)
 \put(10,40){\circle*{2}}
 \put(10,40){\line(1,-2){10}}...
 ...($k$-Kinder)}}
 \put(60,5){\makebox(24,0){$B_0,B_1,\dots,B_{k-1}$}}\end{picture}

Die Teilbäume $B_0,B_1,\dots,B_{k-1}$ sind alle zur verbleibenden Queue zu mergen. Außerdem muß der Min-Pointer aktualisiert werden. Der Zeitaufwand für DeleteMin -Operation ist: \fbox {$\mathcal{O}(\log{N})$}
7.
Delete : Lösche Knoten x:
1-Fall)
x ist min-Wurzel: s.o.
2-Fall)
x ist eine andere Wurzel in der Wurzelliste. Analog zu oben, ohne den Min-Pointer zu aktualisieren.
3-Fall)
x sei nicht Wurzel eines Baumes:
Angenommen, x ist in Baum Bi enthalten:

\begin{picture}
(156,92)
 \put(20,22){\circle*{2}}
 \put(20,22){\line(1,-1){10}}...
 ...){\line(1,1){13.8}}
 \put(53,44){\line(1,-1){13.8}}
 
\thinlines 
 \end{picture}


Im Fall-3 muß unterschieden werden:
3a)
x ist Wurzel:

\begin{picture}
(40,30)
 \put(20,26){\circle*{2}}
 \put(20,26){\line(1,-2){10}}
...
 ...{$x$}}
 \put(3,14){\makebox(35,8){B$_{0}$,B$_{1},\dots$,B$_{i-1}$}}\end{picture}
Siehe (2-Fall)
3b)
x ist in Wurzel des Bi:


\begin{picture}
(22,30)
 \put(10,28){\circle*{2}} 
 \put(10,28){\line(1,-2){10}}...
 ...}
 \multiput(9.7,17.5)(0,5){2}{\bezier{25}(0,0)(-1.25,1.25)(0,2.5)}\end{picture}

So lange 3-te Fall wiederholen (Rekursiv), bis Fall-3a) eintritt
Insgesamt muß die Binomial-Queue ohne Bi mit einer aus $B_0,\cdots,B_{N-1}$ bestehenden Binomial-Queue vereinigt werden.
\fbox {Zeit $\mathcal{O}(\log{N})$}
8.
DecreaseKey : Verkleinere Key(x)
1-Fall)
x ist die min-Wurzel: keine Strukturänderung nötig
2-Fall)
x ist eine andere Wurzel: keine Strukturänderung nötig
3-Fall)
Sonst wie Delete(x) , aber einfügen des Baumes mit Wurzel x und den neuen Key(x) in die Wurzelliste.
\fbox { Kosten $\mathcal{O}(\log {n})$}
\fbox {\parbox[c]{12.45cm}{\textbf{Satz:}
Binomial-Queues haben f\uml {u}r die O...
 ...{\textsf{Initialize}}
 worst-case-Kosten von jeweils $\mathcal{O}(\log{n})$.
}}


next up previous contents
Next: Fibonacci-Heaps Up: Priority Queues Previous: Priority Queues
Abbas-Bardia Kabiri-Jarghouyeh
3/3/1999