¢¡¤£¦¥¤§©

Werbung
http://www.mpi-sb.mpg.de/~sschmitt/info5-ss01
IS
UN
R
S
SS 2001
E R SIT
S
Schmitt, Schömer
SA
IV
A
Grundlagen zu
Datenstrukturen und Algorithmen
A VIE N
Lösungsvorschläge für das 9. Übungsblatt
Letzte Änderung am 3. Juli 2001
Aufgabe 1
a) void rotate_right (node* u)
{
node* v = u->left;
if (u->parent->left == u)
{
u->parent->left = v;
}
else
{
u->parent->right = v;
}
v->parent = u->parent;
u->left = v->right;
u->left->parent = u;
u->parent = v;
v->right = u;
}
// speichere v zwischen
// ist u linkes Kind?
// ja => v links anhaengen
// sonst => v rechts anhaengen
//
//
//
//
//
v’s Vorgaenger ist alter Vorgaenger von u
linkes Kind von u ist B
B’s Vorgaenger ist u
Vorgaenger von u ist v
u haengt rechts unter v
– Die Tiefe von u erhöht sich um 1.
– Die Tiefe von v erhniedrigt sich um 1.
– Die Tiefe der Knoten in A erniedrigt sich um 1.
– Die Tiefe der Knoten in B bleibt gleich.
– Die Tiefe der Knoten in C erhöht sich um 1.
– Die Tiefe aller anderen Knoten im Baum bleibt gleich.
Aufgabe 2
Nach der Eingabe:
17
13
24
10
26
8
27
5
31
9
1
35
6
32
rotate_right(13)
42
17
24
10
26
13
8
27
9
5
31
6
1
35
32
rotate_right(10)
rotate_left(27);
rotate_left(24)
17
42
17
24
8
26
8
26
10
5
1
69
24
10
5
31
27
13
1
13
69
35
27
31
32
42
35
32
rotate_left(26)
42
17
31
8
1
26
10
5
69
13 24
35
27 32
42
Aufgabe 3
Um das Problem zu lösen, muß zunächst die Implementierung binärer Suchbäume dahingehend
geändert werden, daß jeder Knoten v die Anzahl seiner linken und rechten Kinder kennt. Dafür erweitern wir unsere Datenstruktur bin_tree_node um 2 Elemente int nmb_left, int nmb_right.
Bei insert(x) inkrementieren wir für jeden Knoten u, der besucht wird, einfach u->nmb_left,
falls wir im linken Teibaum von u weitersuchen, und u->nmb_right im anderen Fall. Der einzufügende Knoten x besitzt keine Kinder, somit ist u->nmb_right = u->nmb_left = 0. Diese
Änderungen verändern nichts an der Laufzeit der bisherigen Funktionen.
Beim Bestimmen der Anzahl der Knoten, deren Elemente im Intervall [a, b] liegen, bestimmen
wir zunächst die Anzahl der Knoten, deren Elemente kleiner oder gleich b sind. Dabei suchen
wir b binär, und stoßen wir dabei auf einen Knoten v, der kleiner ist als b, addieren wir die
Zahl (v->nmb_left)+1 zu unserer bisher gefundenen Zahl kleinerer Elemente dazu, und suchen
im rechten Teilbaum weiter ( Die +1 addieren wir für den Knoten v selbst dazu ). Existiert ein
Knoten mit Element b im Baum, so addieren wir die Zahl seiner linken Kinder mit dazu, zusätzlich
eins für den Knoten b selbst. Existiert kein solcher Knoten, so endet die Suche, sobald wir auf ein
Blatt treffen. Danach wiederholen wir obigen Algorithmus für a, und ziehen die beiden gefundenen
Werte voneinander ab. Das gibt uns schließich die Anzahl der Knoten im Intervall [a, b].
Laufzeit: Wir haben 2 mal binär gesucht, und da der Baum balanciert ist, hat er logarithmische
Tiefe. Also kostet unsere Suche O(log n) Zeit.
Aufgabe 4
a) Zeigen Sie durch Induktion nach der Tiefe des Baumes: Für einen Rot-Schwarz-Baum mit
n Knoten gilt n ≥ 2st − 1
Wir unterscheiden die normale Tiefe des Baumes t und die schwarze Tiefe st:
Beweis durch Induktion nach der Tiefe t:
IA:
Wenn t=0, dann ist die Wurzel auch ein Blatt, und somit ist der Baum leer.
⇒ st = 0 und n = 0
⇒ 2st − 1 = 20 − 1 = 0 = n
IS:
Sei nun t > 0. Die Wurzel besitzt zwei Kinder, die jeweils Wurzeln eines Teilbaums mit
Tiefe ≤ t − 1 sind. Diese beiden Teilbäume haben n1 bzw. n2 Elemente. Die schwarze Tiefe
dieser beiden Teilbäume ist jeweils entweder = st oder = st − 1, je nachdem, ob die Wurzel
des Teilbaums rot oder schwarz ist. Nach Induktionsvoraussetzung folgt also
n1 ≥ 2st−1 − 1,
n2 ≥ 2st−1 − 1.
Zusammen folgt
n = n1 + n2 + 1 ≥ 2st−1 − 1 + 2st−1 − 1 + 1 = 2st − 1.
b) Es Sei t die Tiefe des Rot-Schwarz-Baumes. Zeigen sie st ≥ 2t .
Aus Eigenschaft 3 können wir jetzt schliessen, dass auf jedem path von der Wurzel bis zu
einem Blatt mindestens jedes zweite Blatt schwarz ist.
Für gerade t gilt also:st ≥
t
2
Für ungerade t gilt aber mit Eigenschaft 2 ebenfalls st ≥ d 2t e
c) Zeigen Sie: Ein Rot-Schwarz-Baum mit n Knoten hat eine Tiefe in der Grössenordnung
O(log(n)).
n ≥ 2st − 1
n + 1 ≥ 2st
log(n + 1) ≥ st
t
log(n + 1) ≥
2
2 ∗ log(n + 1) ≥ t
Aufgabe 5
1. Zuerst erinnern wir uns daran, wie die amortisierte Lauftzeit auf dem 5. Übungsblatt begründet wurde. Es wurde so argumentiert, dass bei n beliebigen enqueue und dequeue
Operationen jedes Element höchstens 4 mal angefasst wird: auf den ersten Stack gepusht,
davon gepoppt, auf den zweiten gepusht und wieder davon gepoppt. Daraus ergibt sich die
amortisiert konstante Laufzeit.Nun bleibt die Frage, was die neue Operation mdequeue daran ändert. Da die Implementierung der alten Teile gleich bleibt und mdequeue auf dequeue
darauf aufbaut, bleibt die informelle Begründung die gleiche. Dies ist nun in den folgenden
Teilen konkret zu beweisen.
Für die Analysen nehmen wir an, dass die Queue während der n Operationen nicht leer wird.
Dies ist insofern eine legitime Vereinfachung, da man die Folge der Operationen in Teilfolgen
mit genannter Eigenschaft aufspalten kann. Für jede dieser Teilfolgen ist auch am Anfang
die Schlange leer, also gelten immer die gleichen Bedingungen. Sei n = n1 + n2 + · · · + nl
und die Laufzeit auf den Teilfolgen amortisiert konstant,
d.h. O(nk )∀1 ≤ k ≤ l, dann ist
Pl
die Gesamtlaufzeit auch amortisiert konstant: O( k=1 nk ) = O(n).
2. Wir bezahlen für das Einfügen pro Element 4 RE ein (eine fürs Einfügen, zwei fürs Umkopieren und eine falls das Element in eine mdequeue Operation verwickelt ist). Für eine dequeue
Operation wird wieder eine RE bezahlt. Daraus folgt, dass wir für eine mdequeue(k) Operation k RE bezahlen müssten. Diese haben wir aber schon beim Einfügen einbezahlt und
somit können wir mdequeue quasi umsonst durchführen. Damit kann es vorkommen, dass
unser Konto trotz leerer Queue noch RE enthält; aber das ist nicht weiter schlimm. Wir
haben nun gezeigt, dass n beliebige Operationen c · n RE verbrauchen. Also ist die Laufzeit
amortisiert konstant.
3. Seien K1 , K2 die Anzahl der Elemente auf dem jeweiligen Keller. Als Potentialfunktion
nehmen wir Φ(Dn ) = 3 · K1 + K2 . Die Voraussetzungen sind erfüllt, da K1 und K2 nie
negativ werden können.
• enqueue: ĉi = ci + Φ(Di ) − Φ(Di−1 ) = 1 + 3 = 4.
• dequeue: ĉi = ci + Φ(Di ) − Φ(Di−1 )
– K2 ist nicht leer: ĉi = 1 − 1 = 0
– K2 ist leer: Nach dem Umkopieren sind K1 Elemente auf dem zweiten Keller. Das
Umkopieren kostet insgesamt 2K1 RE’s.
ĉi = 1 + 2K1 + Φ(Di ) − Φ(Di−1 ) = 1 + 2K1 + K1 − 3K1 = 1.
• mdequeue(k): ĉi = ci + Φ(Di ) − Φ(Di−1 )
– K2 hat mindestens k Elemente: ĉi = k − k = 0.
– K2 hat l Elemente mit 0 ≤ l < k, d.h. zuerst werden diese l Elemente entfernt.
Dann werden alle Elemente aus K1 umkopiert und dann die restlichen k − l Elemente entfernt. Wir erhalten
ĉi = l + 2K1 + (k − l) + Φ(Di ) − Φ(Di−1 ) = k + 2K1 + (K1 − (k − l)) − (3K1 + l) = 0.
Herunterladen