Informatik I 7. Kapitel rot-schwarz-Bäume Rainer Schrader Zentrum für Angewandte Informatik Köln 30. Juni 2008 1 / 55 2 / 55 rot-schwarz-Bäume rot-schwarz-Bäume • wir benutzen in diesem Kapitel wiederum Bäume als Datenstruktur Gliederung • durch Einfüge- und Löschoperationen werden sich die Bäume • Definitionen und Eigenschaften dynamisch verändern • wir wollen dabei stets sicherstellen, dass die entstehenden Bäume • Operationen auf rot-schwarz-Bäumen „balanciert” sind • Sichtbarkeitsproblem • d.h., dass ihre Höhe in der Größenordnung des Logarithmus der Anzahl ihrer Knoten liegt 3 / 55 4 / 55 rot-schwarz-Bäume rot-schwarz-Bäume • Sei T ein binärer Suchbaum • die Knoten seien zusätzlich rot oder schwarz gefärbt • (die Farbe können wir durch ein zusätzliches Bit speichern) Vereinbarung: • wir verwenden Bäume, in denen jeder Knoten zwei Söhne oder keinen Sohn hat • wir stellen dies sicher, indem wir “künstliche” Knoten hinzufügen: T heißt rot-schwarz-Baum, wenn folgendes gilt: • fehlende Knoten werden durch künstliche Knoten aufgefüllt (1) jeder Knoten ist entweder rot oder schwarz, • alle Blätter werden künstlich hinzugefügt (2) die Wurzel und alle Blätter sind schwarz, • die künstlichen Knoten (= Blätter) werden durch Nullzeiger dargestellt (3) beide Kinder eines roten Knotens sind schwarz, • die Schlüssel werden nur in internen Knoten gespeichert (4) jeder Pfad von einem Knoten zu einem Blatt enthält die gleiche Anzahl von schwarzen Knoten. 5 / 55 6 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Beispiel: • Höhe eines Knotens h(v): • Anzahl der Kanten auf einem längsten Pfad von v zu einem Blatt 26 = schwarz 17 = rot 14 21 10 7 16 12 15 • Schwarzhöhe eines Knotens bh(v): 41 19 30 23 28 20 • Anzahl der schwarzen Knoten auf einem Pfad von v zu einem Blatt, ohne v mitzuzählen 47 • eindeutig wegen Eigenschaft (4) 38 35 39 • Im Beispiel: 5 • h(14) = 4 bh(14) = 2 h(T ) = 6 7 / 55 8 / 55 rot-schwarz-Bäume rot-schwarz-Bäume AVL-Bäume (nach Adelson-Velskii und Landis) Ein binärer Baum heißt AVL-Baum, wenn sich in jedem Knoten die Höhen des rechten und des linken Teilbaums um höchstens 1 unterscheiden. • wir empfinden einen Baum als “unbalanciert‘”, wenn sich die Wege von einem Knoten zu Blättern in ihrer Länge stark unterscheiden • die Eigenschaft (4) sichert, dass zumindest die schwarzen Knoten 4 „balanciert” sind A • wir werden sehen, dass die roten Knoten nicht zu sehr stören 2 • d.h. es gilt stets Höhe(T ) = O(log n) 3 B F 2 1 • wir wollen vorher jedoch noch zwei weitere Balancekonzepte diskutieren 1 D E 1 G J 1 H 10 / 55 9 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Lemma AVL-Bäume sind rot-schwarz-Bäume. Rang-Balanciertheit Beweisskizze: • sei T ein binärer Baum • zu jedem Knoten v ∈ T existiere eine Zahl rang(v ) ∈ N • färbe alle Knoten mit gerader Höhe (einschließlich der Blätter) schwarz • ein Knoten mit ungerader Höhe wird genau dann rot gefärbt, wenn die Höhe seines Vater um genau 1 größer ist • T heißt rang-balanciert, wenn folgendes gilt: (1) rang(v ) ≤ rang(Vater (v )) ≤ rang(v ) + 1 (2) rang(v ) < rang(Vater (Vater (v )) 4 A A 2 (3) ist v ein Blatt, so ist rang(v ) = 0 und rang(Vater (v )) = 1 3 B B F F 2 1 1 D 1 G J E G D J E 1 H 1 H 11 / 55 12 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Rot-Schwarz-Baum (1) jeder Knoten ist entweder rot oder schwarz, • umgekehrt gilt aber auch: ein rang-balancierter Baum ist ein (2) die Wurzel und alle Blätter sind schwarz, rot-schwarz-Baum (3) beide Kinder eines roten Knotens sind schwarz, (4) jeder Pfad von einem Knoten zu einem Blatt enthält die gleiche Anzahl von schwarzen Knoten. Lemma T rot-schwarz ⇐⇒ T ist rang-balanciert. rang-balanciert Beweis: Übungsaufgabe (rang(v ) = Schwarzhöhe(v )) (1) rang(v ) ≤ rang(Vater (v )) ≤ rang(v ) + 1 (2) rang(v ) < rang(Vater (Vater (v )) • wir werden daher beide Konzepte synonym verwenden • und statt von Schwarzhöhe auch von Rang sprechen (3) ist v ein Blatt, so ist rang(v ) = 0 und rang(Vater (v )) = 1 • für einen rot-schwarz-Baum setze rang(v ) = Schwarzhöhe(v ) • dann gilt offensichtlich: ein rot-schwarz-Baum ist rang-balanciert 13 / 55 14 / 55 rot-schwarz-Bäume rot-schwarz-Bäume (i) Lemma Sei T rang-balanciert und u ein Knoten mit rang(u) = k . Dann gilt: (i) 1 Höhe(u) 2 ≤ rang(u) ≤ Höhe(u) : • die Aussage ist richtig für k = 0 • sei u ein Knoten vom Rang k ≥ 1 ≤ rang(u) ≤ Höhe(u), (ii) u hat mindestens 2k − 1 interne Knoten als Nachfolger, (iii) Höhe(T ) = 1 Höhe(u) 2 • wenn u keinen Enkel hat, so ist rang(u) = 1 und Höhe(u) = 1 • andernfalls sei v ein Enkel von u maximaler Höhe O(log n). • dann ist Höhe(u) = Höhe(v ) + 2 und Beweis: (iii) folgt aus (i) und (ii): rang(u) ≤ rang(v ) + 2 • sei r die Wurzel von T • nach (i) ist 21 Höhe(T ) ≤ rang(r ) ≤ Höhe(T ) ≤ Höhe(v ) + 2 ≤ 2 · rang(v ) + 2 (per Induktion) = 2 · (rang(v ) + 1) rang(r ) • nach (ii) gilt 2 ≤ |T | = n • damit ist rang(r ) ≤ log n • und Höhe(T ) ≤ 2 log n ≤ 2 · rang(u) und somit rang(u) ≤ Höhe(v ) + 2 = Höhe(u) ≤ 2 · rang(u). 15 / 55 16 / 55 rot-schwarz-Bäume rot-schwarz-Bäume (ii) u hat mindestens 2k − 1 interne Knoten als Nachfolger: • per Induktion über die Höhe von u • ist Höhe(u) = 0, so ist u ein Blatt und k = 0 • dann hat u 2k − 1 = 20 − 1 = 0 interne Nachfolger Folgerung: • die Operationen suche, minimum, maximum, symmetrischer Nachfolger und symmetrischer Vorgänger benötigen rot-schwarz-Bäumen • sei Höhe(u) ≥ 1 • dann hat jeder Sohn von u den Rang mindestens k − 1 • sowie eine Höhe, die echt kleiner ist als Höhe(u) • das gleiche gilt auch für füge_ein und lösche • allerdings können die bisherigen Realisierungen nicht garantieren, dass • per Induktion hat jeder Sohn mindestens 2k −1 − 1 interne Nachfolger • damit beträgt die Anzahl der internen Nachfolger von u mindestens k −1 2 · (2 O(log n) Zeit auf auch nachher noch ein rot-schwarz-Baum vorliegt • wir werden zeigen, dass wir auch dies in O(log n) Zeit erreichen können. k − 1) + 2 ≥ 2 − 1. 17 / 55 18 / 55 rot-schwarz-Bäume rot-schwarz-Bäume • wir verändern Bäume dynamisch durch Einfügen oder Löschen von Knoten Gliederung • Definitionen und Eigenschaften • wir führen danach ggf. zusätzliche Hilfsoperationen (Rotationen) aus • Operationen auf rot-schwarz-Bäumen • diese Rotationen werden helfen, die Eigenschaften (1) (4) wiederherzustellen • Sichtbarkeitsproblem • Rotationen ändern lokal die Zeigerstruktur • dabei bleibt jedoch die Suchbaum-Eigenschaft erhalten 19 / 55 20 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Links- und Rechtsrotationen Leftrotate(T, x) Links−Rotation leftrotate(T,x) Rechts−Rotation rightrotate(T,y) y y = rightson(x) rightson(x) = leftson(y) Vater(leftson(y)) = x Vater(y) = Vater(x) ist x Wurzel von T, so mache y zur Wurzel von andernfalls: ist x linker Sohn seines Vaters, so mache y zum linken Sohn des Vaters von ist x rechter Sohn seines Vaters, so mache y zum rechten Sohn des Vaters von leftson(y) = x Vater(x) = y x rightrotate(T,y) x y α γ leftrotate(T,x) α β γ β T x x • bei Rechtsrotationen muss gelten x 6= NULL, entsprechend y 6= NULL bei Linksrotationen Rightrotate ist symmetrisch zu Leftrotate. • die Suchbaumrelationen bleiben erhalten Laufzeit: O(1) 21 / 55 22 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Illustration: füge_ein(T , u) 7 x 4 11 (1) suche nach u wie in Suchbäumen y 3 6 9 2 18 14 • die Suche endet in einem schwarzen Knoten • denn ein roter Knoten hat zwei (schwarze) Kinder 19 12 17 22 (2) füge u als neuen Knoten mit zwei neuen Blättern ein 20 (3) färbe die neuen Blätter schwarz und u rot 7 y 4 • wir ersetzen somit einen schwarzen Knoten durch einen roten Knoten mit zwei schwarzen Söhnen 18 x 3 2 6 11 9 19 14 12 • daher kann lediglich Bedingung (iii) verletzt sein 22 17 20 23 / 55 24 / 55 rot-schwarz-Bäume rot-schwarz-Bäume (4a) ist u Wurzel, so färbe u schwarz, stop. (5) damit haben wir die folgende Situation: • T ist zulässig gefärbt u • u und w = Vater(u) sind rot • dann kann w nicht die Wurzel sein u • sei x = Vater(u) = Großvater(u) • dann ist x schwarz • die rot-schwarz-Bedingungen sind nur zwischen u und w verletzt (4b) ist w = Vater(u) schwarz, stop. • T ist zulässig gefärbt • wir werden jetzt: w • entweder den Baum durch Rotationen reparieren • oder u • die Verletzung zur Wurzel hin verschieben • und dort beseitigen 26 / 55 25 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Untersuchung der Ränge: (5) u und w = Vater(u) sind rot, x = Vater(w ) = Großvater(u) schwarz • sei r + 1 der Rang von x vor dem Umfärben • die roten Knoten haben dann Rang r + 1 (6) sei w rechter Sohn von x (der andere Fall folgt symmetrisch) (7) hat x nur rote Söhne: • der andere schwarze Knoten hat Rang r • nach dem Umfärben verändern sich die Ränge lokal • vertausche Farben, setze u := x , gehe zu (4) • Tx ist repariert, gehe höher im Baum • sie stören aber die Rangbedingungen nicht, da • x entweder Wurzel ist x x w √ • oder der Vater von x vorher und nachher den Rang r + 2 hat w r+2 r+1 a u a u r+1 r+1 r+1 r+1 Analog, falls u linker Sohn von w r 27 / 55 r+1 r r+1 28 / 55 rot-schwarz-Bäume rot-schwarz-Bäume (8) andernfalls hat x mindestens einen schwarzen Sohn Untersuchung der Ränge: • da w rot ist, muss der Bruder b von u wegen (iii) schwarz sein • sei der Rang von x vor dem Umfärben wieder r + 1 • wir unterscheiden zwei Fälle: • führe eine L-Rotation durch • die roten Knoten haben ebenfalls Rang r + 1 • alle anderen schwarzen Knoten haben Rang r • nach dem Umfärben verändern sich die Ränge wieder lokal • und vertausche die Farben von x und w • der Rang der lokalen Wurzel bleibt aber gleich (8a) u = Rightson(w ) : r+1 w x r+1 r+1 r+1 x w r+1 r u r+1 a u r r r r r b a c b c d r d r • danach ist die Verletzung der Bedingung (iii) beseitigt 29 / 55 30 / 55 rot-schwarz-Bäume rot-schwarz-Bäume (8b) u = Leftson(w ) : • führe eine R- und eine L-Rotation durch und färbe um u x x u w a a u x • füge_ein: O(log n) b d a b Laufzeit: w w c c b c d • Anzahl der Durchläufe von (4)-(7): O(log n) (immer nach oben) d • also insgesamt O(log n) (bei maximal zwei Rotationen). • Untersuchung der Ränge: r+1 r+1 r+1 r+1 r r+1 r+1 r+1 r r+1 r+1 r r r r r r r r r r • danach ist die Verletzung der Bedingung (iii) beseitigt 31 / 55 32 / 55 rot-schwarz-Bäume Entfernung des Knotens z Beispiel: Illustration zum Entfernen: 11 14 2 (7) 7 1 8 5 v 14 2 15 7 1 15 11 15 u 5 16 8 5 u 4 4 3 (8b) L-Rot. 11 7 10 R.Rot. 18 23 14 u u 2 8 2 11 15 u 5 13 (8a) 7 1 20 12 8 14 1 15 4 6 5 4 7 33 / 55 34 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Entferne(T , z ) • sei y schwarz und sei x einziges internes Kind bzw. Blatt • sei y der (interne) Knoten, der aus T entfernt wird • es können zwei Fehler auftreten: • x und Vater (y )(; Vater (x )) sind rot • ist y rot, so bleibt T ein rot-schwarz-Baum: • die Pfade, die y enthielten, haben einen schwarzen Knoten weniger • der Rang aller Knoten bleibt unverändert, • keine zwei roten Knoten sind benachbart. • falls x rot ist: • sei also y schwarz • wenn y ein einziges internes Kind hat, sei x diese Kind, andernfalls Vater(y) sei x ein Blatt Vater(y) Vater(x) y Vater(x) x x x • dann ist x interner Knoten • färbe x schwarz • danach ist der Baum wieder ein rot-schwarz-Baum y x Vater(x) x 35 / 55 36 / 55 rot-schwarz-Bäume rot-schwarz-Bäume • sei x ein „doppelt schwarzer” Knoten, der nicht schon die Wurzel ist • wir betrachten den Fall „x ist linkes Kind“ (rechtes Kind symmetrisch) • ist x schwarz, so ist Vater (x ) unbalanciert • sei w der Bruder von x • w ist nicht Blatt, da sonst Vater(x ) vor dem Löschen die Balance • zum Ausgleich machen wir x „doppelt schwarz“ • dann stimmt die Farbbalance entlang von Pfaden verletzt hätte • aber x ist falsch gefärbt B • wir schieben die doppelte Farbe schrittweise nach oben bis wir x a) einen roten Knoten erreichen: ; färbe ihn schwarz b) oder die Wurzel erreichen: ; entferne zusätzliches schwarz w D A c) oder geeignete Rotation und Umfärbungen machen können a E C b d c 38 / 55 37 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Fall 1: w ist rot Fall 2: w ist schwarz, beide Söhne von w sind schwarz • dann sind Vater(x ) und die Söhne von w schwarz • vertausche die Farben von w und Vater(x ) • färbe x einfach schwarz und w rot • schiebe schwarz zum Vater von x : • führe eine Linksrotation im Vater(x ) durch • danach ist der Bruder von x schwarz • ist Vater(x ) rot, so färbe ihn schwarz, STOP • (wenn vorher Fall 1 eingetreten ist, ist Vater(x ) rot) • andernfalls haben wir die doppelte Färbung nach oben verschoben • ; Fall 2,3 oder 4 • (und die Ränge bleiben lokal erhalten) • setze x = Vater(x ) und iteriere • (die Ränge bleiben lokal erhalten) r+1 r+1 B D Fall 1 x r+1 w A r+1 r−1 x C r E r E r−1 w C x B D A r r+1 r B D Fall 2 A r r−1 r−1 D D A D C 39 / 55 r w x r B r−1 E r−1 r−1 C r−1 E 40 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Fall 3: w ist schwarz, der linke Sohn ist rot, der rechte ist schwarz Fall 4: w ist schwarz, der rechte Sohn ist rot • vertausche die Farben von w und seinem linken Sohn • färbe w wie Vater(x ), Vater(x ) und den rechten Sohn von w schwarz, • führe eine Rechtsrotation an w aus • führe eine Linksrotation im Vater(x ) aus • danach ist der neue Bruder w von x schwarz mit einem roten rechten • entferne die doppelte Färbung von x Sohn • ; Fall 4 • (und die Ränge bleiben lokal erhalten) • danach ist T ein rot-schwarz-Baum r+1 r+1 B r+1 x B A r r−1 D A r−1 r E r-1 r B D r C C D C r r-1 r w x r w A B Fall 3 Fall 4 x r+1 D x E A r E D r-1 w C r-1 D r−1 r−1 E Laufzeit: O(log n). 42 / 55 41 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Zusammenfassung Rot-schwarz-Bäume bilden eine Datenstruktur, die die folgenden Operationen auf dynamischen Mengen unterstützt: Gliederung • suche • bestimme das Minimum • grundlegende Definitionen • Operationen auf rot-schwarz-Bäumen • bestimme das Maximum • bestimme den Vorgänger einer symmetrischen Durchmusterung • bestimme den Nachfolger einer symmetrischen Durchmusterung • das Sichtbarkeitsproblem • füge ein • lösche Die Laufzeiten betragen jeweils O(log n). 43 / 55 44 / 55 rot-schwarz-Bäume rot-schwarz-Bäume 9 9 Chip (n Zellen) 8 A Chip (n Zellen) 8 A kompaktieren 7 6 B 6 B C Mindestabstände 5 C D einhalten! 4 Mindestabstände 5 kompaktieren 7 3 D einhalten! 4 2 E F 3 1 2 0 E F 1 0 0 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10 11 12 • die relevanten Paare sind die, die sich „sehen” können 10 11 12 (A, D) (A, E ) (B, E ) (C, F ) (D, E ) • ein integrierter Schaltkreis soll kompaktifiziert werden • dazu sollen die Blöcke in y Richtung zusammengeschoben werden • formal: zwei Paare S, S 0 sind gegenseitig sichtbar, wenn gilt: • es existiert eine vertikale Linie, die S und S 0 , aber kein Element zwischen S und S 0 schneidet • dabei sollen jeweils Mindestabstände eingehalten werden 45 / 55 46 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Beobachtung: 9 Beim vertikalen (horizontalen) Sichtbarkeitsproblem spielen die Höhen (Breiten) der Zellen keine Rolle. Chip (n Zellen) 8 A kompaktieren 7 6 B C Mindestabstände 5 D ; Reduktion auf südliche Grenzen (bei vertikaler Sichtbarkeit): einhalten! 4 3 2 E F 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 9 8 A 7 6 Naives Verfahren: B 5 D C 4 • Überprüfung aller `n ´ 2 3 Paare auf vertikale (horizontale) Sichtbarkeit 2 E F 1 • ; Horizontale Segmente, linke und rechte Koordinaten: (xl (A), xr (A)) = (1, 4) (xl (B), xr (B)) = (6, 8) .. . 2 0 Ω(n ) Laufzeit 0 47 / 55 1 2 3 4 5 6 7 8 9 10 11 12 Vertikale Koordinaten: y (A) = 7 y (B) = 5 .. . 48 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Weitere Beobachtung: Die Sichtbarkeiten können durch vertikale Linien dargestellt werden, die sich gegenseitig nicht schneiden. Satz (ohne Beweis) Ein planarer Graph mit n ≥ 3 Knoten hat höchstens 3n − 6 Kanten. ⇒ Es kann nur 9 O(n) viele Sichtbarkeitspaare geben. 8 A 7 Sei L eine Datenstruktur, die die Operationen unterstützt: 6 B 5 D • füge_ein • lösche C 4 3 2 E • Vorgänger • Nachfolger F 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 Zur einfacheren Darstellung nehmen wir an, dass die x -Koordinaten der Der korrespondierende Graph mit n Knoten ist planar, d.h. er kann ohne Anfangs- und Endpunkte paarweise verschieden sind. Kantenüberkreuzungen gezeichnet werden. 49 / 55 50 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Idee eines Scanline-Ansatzes • wir fahren den Bereich von links nach rechts mit einer vertikalen Scan-Linie ab Datenstrukturen • dabei halten wir nur an Anfangs- oder Endpunkten von Segmenten • dazu verwenden wir eine sortierte Liste aller x -Koordinaten dieser • zu jedem Segment S existieren Angaben (xl , S, l ), (xr , S, r ) und (y , S) Punkte • sortiere die 2n Werte (xl , S, l ), (xr , S, r ) aufsteigend nach • die y -Koordinaten der Segmente fassen wir als Schlüssel auf x -Koordinaten ; O(n log n) • sei Q eine Schlange, die diese Werte aufsteigend enthält • sei T ein rot-schwarz-Baum, der die aktuellen Segmente aufnimmt • die Nachbarsegmente werden durch die Operationen „Nachfolger” bzw. • während des Scannens verwalten wir dynamisch die Menge aller Segmente, die von der Scan-Linie geschnitten werden: • wird der Anfangspunkt eines Intervalls erreicht, so fügen wir das Intervall in die Menge ein „Vorgänger” in der symmetrischen Durchmusterung bestimmt • wird der Endpunkt eines Intervalls erreicht, so entfernen wir das Intervall aus der Menge • die Sichtbarkeitsrelation wird durch benachbarte Schlüsselwerte bestimmt 51 / 55 52 / 55 rot-schwarz-Bäume rot-schwarz-Bäume Skizze eines scan-line-Ansatzes while im Beispiel: Anfang von Q Q6= ∅ do entferne das nächste Element (x,S,e) aus Q if e = l do füge (y(S),S) in T ein sei (y’,S’) Vorgänger in T falls S’ existiert, gib (S,S’) aus sei (y”,S”) Nachfolger in T falls S” existiert, gib (S,S”) aus else do // (1, A, l ) (1, E , l ) (2, D, l ) (3, D, r ) (4, A, r ) (6, B, l ) (7, E , r ) (8, B, r ) (9, C, l ) (9, F , l ) (10, F , r ) (11, C, r ) ∅ e = r sei (y’,S’) Vorgänger in T sei (y”,S”) Nachfolger in T falls S’, S” existieren, gib lösche (y(S),S) aus T end if end while (S’,S”) aus 53 / 55 rot-schwarz-Bäume • einschließlich der Duplikate werden O(n) Paare ausgegeben • implementiert man Q einfach als Array und sortiert etwa mit Heapsort, so benötigt das Verfahren O(n log n) Zeit für die Erstellung von Q und O(1) Zeit für jedes Entfernen aus Q • im Rot-Schwarz-Baum T benötigen wir O(log n) Zeit für jede Operation • daraus ergibt eine Gesamtlaufzeit von O(n log n) • offensichtlich benötigt das Verfahren O(n) Speicherplatz. 55 / 55 Inhalt von L (7, A) (1, E ), (7, A) (1, E ), (4, D), (7, A) (1, E ), (7, A) (1, E ) (1, E ), (5, B) (5, B) ∅ (4, C) (1, F ), (4, C) (4, C) ∅ Ausgabe (E , A) (D, E ), (D, A) (E , A) (B, E ) (C, F ) 54 / 55