TU Ilmenau, Fakultät für Informatik und Automatisierung FG Komplexitätstheorie und Effiziente Algorithmen Univ.-Prof. Dr. M. Dietzfelbinger, M. Sc. Philipp Schlag, M. Sc. Stefan Walzer https://www.tu-ilmenau.de/iti/lehre/lehre-ss-2017/aud/ Algorithmen und Datenstrukturen – Übung 5 Besprechung am 9. und 10. Mai 2017 Aufgabe 0 (Löschen in AVL-Bäumen) In der Vorlesung wurde gezeigt, wie man in einen AVL-Baum T einen Knoten mit Schlüssel x und Daten r einfügt. Im Folgenden untersuchen wir, wie man einen Knoten mit Schlüssel x aus T wieder entfernen und die Balancebedingung dabei erhalten kann. Um einen Knoten mittels AVL delete(T, x) zu löschen, gehen wir zunächst wie bei gewöhnlichen binären Suchbäumen vor: Wir suchen den Knoten v mit Schlüssel x in T . Falls es keinen solchen Knoten gibt, sind wir fertig, andernfalls sind zwei Fälle zu unterscheiden: (1) Falls v (mindestens) einen leeren Unterbaum besitzt, genügt es, den Zeiger des Vaters von v auf den anderen Unterbaum von v umzubiegen und v zu löschen. (2) Falls beide Unterbäume von v nicht-leer sind, suchen wir den Inorder-Nachfolger u von v, d. h. den Knoten mit dem kleinsten Schlüssel im rechten Unterbaum von v, mittels AVL extractMin, hängen diesen an die Stelle von v um und löschen v. Allerdings ist es möglich, dass nun die Balancebedingung an einem Knoten verletzt ist. Um diese (wenn nötig) wiederherzustellen, laufen wir den Weg p von der Stelle, an der v gelöscht (Fall (1)) bzw. u ausgehängt wurde (Fall (2)), zur Wurzel, bestimmen an jedem Knoten die neuen Balancefaktoren und führen gegebenenfalls eine Einfach- oder Doppelrotation aus. (Im Unterschied zur Einfüge-Operation kann es hier durchaus nötig sein, dass an mehreren Knoten eine solche Rotation durchgeführt werden muss.) Wir betrachten den Unterbaum T ′ = (T1 , w, T2 ) von T mit Wurzel w, welche auf dem Weg p liegt. Da wir den Baum von unten beginnend rebalancieren, können wir annehmen, dass T1 und T2 (evtl. durch Rebalancierung wiederhergestellte) AVL-Bäume sind. Zunächst bestimmen wir den Balancefaktor bal(w) = d(T2 ) − d(T1 ). Falls bal(w) ∈ {−1, 0, 1} gilt, ist T ′ bereits höhenbalanciert. Andernfalls gilt bal(w) ∈ {−2, 2} und wir müssen rebalancieren. Dazu nehmen wir bal(w) = 2 an, d. h. T2 ist zu tief. (Der Fall bal(w) = −2 wird symmetrisch behandelt.) Insbesondere hat T2 mindestens Tiefe 1. Sei p′ ein einfacher Weg maximaler Länge von w zu einem Blatt in T2 . (p′ = (w, w′ , w′′ , . . . ) hat also mindestens Länge 2.) Wir unterscheiden zwei Fälle: (1) p′ beginnt mit “rechts-rechts”, d. h. w′ ist rechtes Kind von w und w′′ ist rechtes Kind von w′ . Insbesondere gilt bal(w′ ) ≥ 0. Wie in Abbildung 1 dargestellt, können wir T2 mit Hilfe einer Linksrotation rebalancieren. (2) p′ beginnt mit “rechts-links”, d. h. w′ ist rechtes Kind von w und w′′ ist linkes Kind von w′ . Insbesondere gilt bal(w′ ) ≤ 0. Wie in Abbildung 2 dargestellt, können wir T2 mit Hilfe einer Rechts-Links-Doppelrotation rebalancieren. Um die Operation AVL delete(T, x) zu realisieren (und wieder einen AVL-Baum zu erhalten), genügt es also, die Lösch-Operation wie bei gewöhnlichen binären Suchbäumen umzusetzen und anschließend an jedem Knoten auf dem Weg vom gelöschten Knoten zur Wurzel höchstens eine Einfach- oder Doppelrotation durchzuführen. Besitzt der AVL-Baum n innere Knoten, benötigen wir dafür insgesamt Zeit O(log n). 2 Algorithmen und Datenstrukturen – Übung 5 T ′: T ′: w w′ w′ w =⇒ T1 T21 T1 T21 T22 T22 Abbildung 1: Rebalancierung durch Linksrotation in Fall (1) T ′: T ′: w w′′ w′ w′ w =⇒ w ′′ T1 ′ T21 ′′ T21 T22 T1 ′ T21 ′′ T21 T22 Abbildung 2: Rebalancierung durch Rechts-Links-Doppelrotation in Fall (2) Beispiel. In Abbildung 3 sehen wir einen AVL-Baum T (mit annotierten Balancefaktoren), aus dem der Knoten v mit Schlüssel 1 gelöscht werden soll. Zunächst wird der Knoten wie bei allgemeinen binären Suchbäumen in T gesucht und aus dem Baum entfernt (Schritt (1)). Danach werden von unten nach oben alle Knoten auf dem Weg p vom gelöschten Knoten zur Wurzel dahingehend überprüft, ob sich der Balancefaktor geändert hat. (Der Knoten mit Schlüssel 2, der umgehängt wurde, hat noch immer denselben Balancefaktor.) • Der Knoten mit Schlüssel 3 hat den neuen Balancefaktor 0, es ist nichts zu tun. (Schritt (2)) • Der Knoten w mit Schlüssel 5 hat den neuen Balancefaktor 2, d. h. wir müssen rebalancieren. Der längste einfache Weg p′ von w zu einem Blatt (hier: Knoten mit Schlüssel 6) beginnt mit “rechts-links”. Daher können wir den Baum durch eine Rechts-Links-Doppelrotation an w rebalancieren, der neue Balancefaktor ist 0 (Schritt (3)). Der so entstandene binäre Suchbaum ist tatsächlich wieder ein AVL-Baum. 3 Algorithmen und Datenstrukturen – Übung 5 T: 1 5 −1 −1 3 10 1 −1 0 1 4 −1 8 12 −1 0 0 2 7 0 9 11 0 6 ⇓ (1) 1 5 −1 −1 3 10 0 −1 0 2 4 −1 8 12 −1 0 7 0 9 11 0 6 ⇓ (2) 1 5 0 −1 w 3 10 0 −1 0 2 4 −1 w′ 8 −1 12 0 w′′ 7 0 9 11 0 6 ⇓ (3) 0 8 0 1 w′′ 5 0 10 −1 w 3 7 0 0 2 4 0 −1 w′ 9 0 12 0 6 Abbildung 3: Beispiel-Aufruf AVL delete(T, 1) 11 Algorithmen und Datenstrukturen – Übung 5 4 Aufgabe 1 (AVL-Bäume) Gegeben ist die Folge 1 12 2 5 4 8 6 11 3 13 10 7 9 14 15 16 von 16 Schlüsseln. (a) Fügen Sie die Schlüssel nacheinander in einen (anfangs leeren) AVL-Baum ein und zeichnen Sie den Baum vor und nach jeder Rotation! (b) Finden Sie eine Einfügereihenfolge der Schlüssel, die den gleichen Baum wie in (a) ohne Rotationen erzeugt! (c) Löschen Sie die Schlüssel 1, 12, 16, 7 und 6 und zeichnen Sie den Baum vor und nach jeder Rotation! Aufgabe 2 (Tiefe von 2-3-Bäumen) Zeigen Sie, dass folgende Aussagen für einen 2-3-Baum T der Tiefe h (Level 0, 1, . . . , h) gelten: (a) T besitzt mindestens 2h+1 − 1 Knoten und mindestens 2h+1 − 1 Schlüssel. (b) T besitzt höchstens 3h+1 −1 2 Knoten und höchstens 3h+1 − 1 Schlüssel. (c) Welche Aussagen über die Tiefe h im Zusammenhang mit der Schlüsselanzahl n können Sie ableiten? Aufgabe 3 (Rot-Schwarz-Bäume) Ein (linksgeneigter) Rot-Schwarz-Baum ist ein binärer Suchbaum, in dem jede Kante mit der Farbe rot oder schwarz eingefärbt ist, wobei folgende Regeln eingehalten werden: (i) Kanten zu (leeren!) Blättern sind schwarz. (ii) Auf keinem Weg im Baum folgen zwei rote Kanten aufeinander. (iii) Wenn ein Knoten nur eine rote Ausgangskante hat, so führt diese zum linken Kind. (iv) Auf jedem Weg von der Wurzel zu einem Blatt liegen gleich viele schwarze Kanten. Die Schwarz-Tiefe b(v) eines Knotens v in einem Rot-Schwarz-Baum T ist die Anzahl der schwarzen Kanten auf dem Weg von v zu einem Blatt; die Schwarz-Tiefe b(T ) des Baumes T ist die Schwarz-Tiefe der Wurzel von T . Zeigen Sie: (a) Ein Rot-Schwarz-Baum T mit Schwarz-Tiefe b(T ) hat mindestens 2b(T ) − 1 innere Knoten. (b) Die Tiefe d(T ) eines Rot-Schwarz-Baums T mit n inneren Knoten ist O(log n).