7.1.3 k-Level-Buckets
Die Verallgemeinerung von 2-Level-Buckets f¨ uhrt zu
k-Level-Buckets. Diese bestehen dann aus k Arrays der L¨ ange
l√
kC
m. Dadurch lassen sich die Speicher- und Zeitkomplexit¨ at
weiter verbessern, der Implementierungsaufwand steigt jedoch
stark an.
7.2 van Emde Boas-Priority Queues Universum U , |U | = N, U ⊂
N. Hier: U = {0, 1, . . . , N − 1}.
Wir untersuchen hier eine bessere Priority Queue f¨ ur den Fall
n ≥ log N .
. . . . . .
0 N −1
0 1 1 0 . . . 1 0 . . . 1
- - - - q
q A
A U
q
?
q
?
· · · ·
O
Delete
. . . . . .
0 N −1
0 1 1 0 . . . 0 0 . . . 1
- - -
q
q A
A U
q
· · · ·
? HH
@@ @@
Insert Baum mit √
N Verzweigungen
Notation
Sei
k ∈
N, k ≥ 2 k
0=
k 2
k
00= k
2
x ∈ [0..2
k− 1] (x hat ≤ k Bits) x
0=
j
x 2
k00k
(x
0vordere H¨ alfte von x) x
00= x mod 2
k00(x
00hintere H¨ alfte von x) Sei
S = {x
1, . . . , x
m} ⊆ [0..2
k− 1] .
Definition 66
Eine k-Struktur T f¨ ur S besteht aus:
1
der Zahl T.size = |{x
1, . . . , x
m}| = |S| = m;
2
einer doppelt verketteten Liste T.list, die die Elemente von S in aufsteigender Reihenfolge enth¨ alt;
3
einem Bitvektor T.b[0..2
k− 1] mit T.b[i] =
01, falls
i6∈Si∈Seinem Zeiger (Pointer) Vektor T.p[0 . . . 2
k− 1]. Falls T.b[i] = 1, dann zeigt T.p[i] auf i in der Liste aus 2.
4
einer k
0-Struktur T.top und einem Feld T.bottom[0 . . . 2
k0− 1]
von k
00-Strukturen. Falls m = 1, dann T.top, T.bottom und
die zugeh¨ origen k
00-Strukturen leer, T.size = 1. T.list = {x},
der Bitvektor wird nicht ben¨ otigt. Falls m > 1, dann ist T.top
eine k
0-Struktur f¨ ur die durch {x
01, x
02, . . . , x
0m} gegebene
Menge, und f¨ ur jedes y ∈ [0 . . . 2
k0− 1] ist T.bottom[y] eine
k
00-Struktur f¨ ur die Menge {x
00i; 1 ≤ i ≤ m; y = x
0i}
Beispiel 67
k = 4, S = {2, 3, 7, 10, 13}, T.size = 5:
T.p ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ ⊥ ⊥
0 N −1
T.b 0 0 1 1 0 0 0 1 0 0 1 0 0 1 0 0
2 0010
3 0011
7 0111
10 1010
13 1101
- - - -q
q A
A U
q
? q
? q
T.list
?T.top ist 2-Struktur f¨ ur {0, 1, 2, 3}
T.bottom[0] ist eine 2-Struktur f¨ ur {2, 3}
T.bottom[1] ist eine 2-Struktur f¨ ur {3}
T.bottom[2] ist eine 2-Struktur f¨ ur {2}
T.bottom[3] ist eine 2-Struktur f¨ ur {1}
Operation Succ(x) findet min{y ∈ S; y > x} in der k-Struktur T.
if k = 1 or T.Size ≤ 2 then naive Suche
elif x ≥ max in T.list then return Succ(x) gibt’s nicht else
x
0:=
jx 2k00
k
; x
00:= x mod 2
k00;
if T.top.b[x
0] = 1 and x
00< max{T.bottom[x
0]} then return x
0· 2
k00+ Succ(x
00, T.bottom[x
0])
else
z
0:=Succ(x
0, T.top); return z
0· 2
k00+ min{T.bottom[z
0]}
fi
fi
JJ
HH HH H H
J J J J J J
JJ
T.top
T.Bottom[0]
T.Bottom[1]
T.Bottom
h2
k0
− 1
i2
k0
x
succ(x)
−−−−→
Kosten:
T(k) ≤ c + T(
k 2
) = O(log k) .
Lemma 68
Die Succ-Operation hat Zeitbedarf O(log k).
Beweis:
√
Insert Operation:
falls x bereits in Priority Queue, dann fertig bestimme Succ(x, T), f¨ uge x davor ein bestimme x
0und x
00behandle die entsprechenden Unterstrukturen rekursiv:
Insert(x
0,T.top), Insert(x
00,T.bottom[x
0]) (nur ein nicht trivialer rekursiver Aufruf)
Zeitbedarf: naiv O(log
2k), Optimierung: das oberste Succ tut
alles ⇒ O(log k).
Delete Operation:
Komplexit¨ at von Delete in k-Struktur: O(log k)
Kosten der Initialisierung: ∼ Gr¨ oße der Datenstruktur
Platzbedarf f¨ ur k-Struktur: Sei S(k) der Platzbedarf f¨ ur eine k-Struktur. Dann gilt:
S(1) = c
S(k) = c2
k+ S(k
0) + 2
k0S(k
00) f¨ ur k ≥ 2 Wir ersetzen zur Vereinfachung:
S(k) = c2
k+ S( k
2 ) + 2
k2S( k
2 )
Lemma 69
S(k) = O(2
k· log k)
Beweis:
Zeige: S(k) := c
02
klog k funktioniert.
F¨ ur k = 1 ist das klar.
Beweis (Forts.):
Rekursionsschritt:
Platz f¨ ur k-Struktur ≤ c2
k+ c
02
k2(log k − 1) + 2
k2c
02
k2(log k − 1)
= c2
k+ c
02
k2(1 + 2
k2)(log k − 1)
= c2
k+ c
02
k2(2
k2log k + log k − 2
k2− 1)
≤ c2
k+ c
02
k2(2
k2log k + log k − 2
k2)
≤ c
02
klog k , falls
c2
k+ c
02
klog k + c
02
k2log k − c
02
k≤ c
02
klog k
⇔ c
02
k2log k ≤ (c
0− c)2
k⇔ c
0− c
c
0≥ log k
2
k(gilt f¨ ur c
0groß genug.)
Satz 70
Sei N = 2
k, Universum U = {0, . . . , N − 1}. Wird eine Teilmenge S ⊆ U durch eine k-Struktur dargestellt, dann ben¨ otigen die Operationen Insert, Delete und FindMin jeweils Zeit O(log log N ), die Initialisierung Zeit O(N log log N ). Der Platzbedarf ist
ebenfalls O(N log log N ).
Beweis:
s.o.
Literatur zu van Emde Boas-Priority Queue:
Kurt Mehlhorn:
Data structures and algorithms 1: Sorting and searching, pp. 290–296,
EATCS Monographs on Theoretical Computer Science, Springer Verlag: Berlin-Heidelberg-New York-Tokyo, 1984
P. van Emde Boas, R. Kaas, E. Zijlstra:Design and implementation of an efficient priority queue
Math. Systems Theory 10 (1976), pp. 99–1277.3 Radix-Heaps
Radix-Heaps stellen eine M¨ oglichkeit zur effizienten Realisierung von Priority Queues dar, wobei ¨ ahnliche Randbedingungen wie bei den 2-Level-Buckets vorausgesetzt werden. Dabei wird die
amortisierte Laufzeit der langsamsten Zugriffsfunktion im Vergleich zu diesen verbessert, n¨ amlich von O( √
C) auf O(log C). C bezeichne wie bei den 2-Level-Buckets die maximale Differenz zwischen zwei Schl¨ usseln im Heap.
Die Grundidee besteht darin, anstelle einer Hierarchie von Buckets
konstanter Gr¨ oße solche mit exponentiell zunehmender Gr¨ oße zu
verwenden. Somit sind nur noch O(log C) Buckets zur Verwaltung
der Elemente im Heap n¨ otig. Wie bei 2-Level-Buckets h¨ angt die
Laufzeit der “teueren“ Operationen direkt von der Anzahl der
Buckets ab.
pppppppppppppppppppp
0 1 2 4 8 16
1
z }| {
1
z }| {
2
z }| {
4
z }| {
8
z }| {
B = dlog(C + 1)e + 1 Buckets Randbedingungen:
Schl¨ ussel ∈
N0max. Schl¨ ussel − min. Schl¨ ussel stets ≤ C
Monotonie von ExtractMin
Implementierung:
B := dlog(C + 1)e + 1 Buckets b[0..B − 1]
(untere) Schranken f¨ ur Buckets u[0..B]
Index b no[x] des aktuellen Buckets f¨ ur x Invarianten:
i)
u[i] ≤ Schl¨ ussel in b[i] < u[i + 1]
ii)