VL-11: Rot-Schwarz Bäume
(Datenstrukturen und Algorithmen, SS 2017) Janosch Fuchs
SS 2017, RWTH
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 1/41
Organisatorisches
• Vorlesung: Gerhard Woeginger (Zimmer 4024 im E1) Sprechstunde: Mittwoch 11:15–12:00
• Übungen: Tim Hartmann, David Korzeniewski, Björn Tauer Email: dsal-i1@algo.rwth-aachen.de
• Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php
• Nächste Vorlesung:
Dienstag, Mai 30, 16:15–17:45 Uhr, Aula 1 (Mai 25 = Feiertag; keine Vorlesung)
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 2/41
Rot-Schwarz Bäume
• Einführung
• Einfügen in Rot-Schwarz Bäumen
• Löschen in Rot-Schwarz Bäumen
Einführung
Hauptproblem der Suchbäume: Die Effizienz der Operationen hängt von der Höhe des Baumes ab
I
Einerseits: Je balanzierter der Suchbaum, desto besser
I
Andererseits: Dauerndes Rebalanzieren kostet Zeit!!
I
Andererseits: Wie stellt man effizient fest, ob Baum balanziert ist?
I
Andererseits: Soll man Zusatzinformationen darüber abspeichern?
Grundidee von Rot-Schwarz-Bäumen (Rudolf Bayer, 1972)
1. Zwei Arten von Knoten: Schwarze Knoten werden strikt balanziert, rote Knoten dienen nur als Schlupf
2. Anteil der Schlupfknoten muss beschränkt bleiben
Also: aufgeweichte Balanziertheitsanforderungen, und wenig zusätzlicher
Speicherplatz (1 Bit pro Knoten für Farbe)
Rot-Schwarz-Bäume (1)
Rot-Schwarz-Eigenschaft
Ein binärer Suchbaum erfüllt die Rot-Schwarz-Eigenschaft, wenn gilt:
1. Jeder Knoten ist entweder rot oder schwarz gefärbt.
2. Die Wurzel ist schwarz.
3.
null-Zeiger (fehlendes Kind, hier enden die Pfade) betrachten wir als externe Knoten mit Farbe schwarz.
4. Jeder nicht-externe Knoten hat genau zwei Kinder.
Jeder rote Knoten hat genau zwei schwarze Kinder.
5. Für jeden Knoten x gilt: alle Pfade, die im Knoten x starten und in einem externen Knoten enden, enthalten die selbe Anzahl an schwarzen Knoten.
So ein Baum heisst dann Rot-Schwarz-Baum (red-black tree, RBT).
Anmerkung: In den Algorithmen verwenden wir für
null-Zeiger (externe Knoten) die Notation
null.color(
== BLACK).
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 5/41
Rot-Schwarz-Bäume (2)
(schwarze) externe Knoten roter Knoten mit
Schwarz-Höhe 3
2614
7 12
19 23
41
47
28 38
16
21 17
10
3
15 20
30
35 39
Definition: Schwarz-Höhe (black height, bh)
I
Die Schwarz-Höhe eines externen Blattes bh(
null) = 0.
I
Die Schwarz-Höhe bh(x ) eines Knotens x ist die Anzahl schwarzer Knoten bis zu einem externen Blatt (Knoten x selbst ausgenommen).
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 6/41
Rot-Schwarz-Bäume (3)
Zeichnet man die roten Knoten immer auf der selben Höhe wie ihren Vater ein, dann erhält man:
Schwarzhöhe
26
41
47 14
19 23
16
21
7 12
3 15 20 28 35 38 39
17
10 30
Anmerkung:
Die externen Knoten werden in Zeichnungen oft weggelassen.
Definition
Die Schwarz-Höhe bh(t) eines RBT t ist die Schwarz-Höhe der Wurzel.
Elementare Eigenschaften von Rot-Schwarz-Bäumen
Lemma
Ein Rot-Schwarz-Baum t mit Schwarzhöhe h = bh(t)
I
enthält mindestens 2
h− 1 innere Knoten.
I
enthält höchstens 4
h− 1 innere Knoten.
Beweis: Induktion über die Höhe des Baumes.
Theorem
Ein RBT mit n inneren Knoten hat Höhe höchstens 2 log
2(n + 1).
I
Ergo: Ein RBT ist ein relativ balanzierter BST.
I
Ergo: Suchen benötigt nur Θ(log n) Zeit.
I
Ergo: Für
bstMin,
bstSucc, etc. gilt dasselbe.
I
Mit Einfügen und Löschen werden wir uns noch beschäftigen.
Beweisskizze (zum Nachlesen zu Hause)
Lemma
Es sei x ein Knoten in einem RBT. Dann enthält der Teilbaum mit Wurzel x mindestens 2
bh(x)− 1 innere Knoten.
Beweis: Induktion über die Höhe h(x) des Knotens x . Basis: Wenn h(x ) = 0, dann ist x ein Blatt.
Induktionsschritt: Wenn h(x ) ≥ 1, so hat x zwei Kinder y
Lund y
R. Für jedes Kind y von x gilt:
I
h(y) ≤ h(x ) − 1, und
I
Wenn y rot, dann bh(y ) = bh(x); andernfalls bh(y) = bh(x ) − 1 Induktionsannahme liefert: Der Teilbaum mit Wurzel y hat mindestens 2
bh(x)−1− 1 innere Knoten.
(Teilbaum mit Wurzel y
L) plus (Teilbaum mit Wurzel y
R) plus (x ) ergibt zusammen mindestens (2
bh(x)−1− 1) + (2
bh(x)−1− 1) + 1 = 2
bh(x)− 1 innere Knoten für den Teilbaum mit Wurzel x . qed
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 9/41
Einfügen in Rot-Schwarz Bäumen
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 10/41
Wiederholung: Einfügen in einen BST / Beispiel
Beispiel
15 5
3 12
10
6
14
16
20
17 31
15 5
3 12
10
6
14
16
20
17
18 31 bstIns(t, Node(18))
Einfügen von Schlüssel k in einen RBT: Grundidee
Einfügen
Zum Einfügen in einen RBT gehen wir zunächst wie beim BST vor:
I
Finde einen geeigneten freien Platz.
I
Hänge den neuen Knoten an.
Es bleibt die Frage nach der Farbe:
I
Färben wir den neuen Knoten schwarz, dann verletzen wir in der Regel die Schwarz-Höhen-Bedingung.
I
Färben wir ihn aber rot, dann könnten wir die Farbbedingungen verletzen (rote Knoten haben keine roten Kinder).
Wir färben den Knoten daher rot (eine Schwarz-Höhen-Verletzung wäre schwieriger zu behandeln; Rot ist lokale, schwarz ist globale Eigenschaft)
I
Behebe im letzten Schritt die mögliche Farbverletzung.
Einfügen in einen RBT: Algorithmus, Teil 1
1 v o i d r b t I n s ( T r e e t , N o d e n o d e ) { 2 // F u e g e n o d e in den B a u m t ein
3 b s t I n s ( t , n o d e ) ; // E i n f u e g e n wie b e i m BST 4 n o d e . l e f t = n u l l ;
5 n o d e . r i g h t = n u l l ; 6 n o d e . c o l o r = RED ;
7 // e i n g e f u e g t e r K n o t e n i m m e r z u n a e c h s t rot
8 // s t e l l e Rot - S c hw ar z - E i g e n s c h a f t ggf . w i e d e r her 9 r b t I n s F i x ( t , n o d e ) ;
10 }
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 13/41
Einfügen: Was kann passieren? (1)
c
node
c node
c
node
c node
I
Der neu eingefügte Knoten ist immer rot.
I
Ist Vaterknoten c schwarz, haben wir kein Problem.
I
Ist Vaterknoten c aber rot, so liegt eine Rot-Rot-Verletzung vor, die wir behandeln müssen.
I
Die beiden unteren Fälle lassen sich symmetrisch zu den oberen Fällen lösen. Daher diskutieren wir nur die oberen Situationen.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 14/41
Einfügen: Was kann passieren? (2)
Wir müssen nun Grossvater d und Onkel e mit berücksichtigen:
d
c e
d
c e
I
Der Grossvater des eingefügten Knotens war schwarz, denn es handelte sich vor dem Einfügen um einen korrekten RBT.
Fall 1
Ist Onkel e rot, dann stellen wir durch Umfärben von c und e auf schwarz sowie d auf rot die Rot-Schwarz-Eigenschaft lokal wieder her.
I
Zwei Ebenen weiter oben kann nun eine Rot-Rot-Verletzung vorliegen, die nach selben Schema iterativ aufgelöst wird.
I
Ist d allerdings die Wurzel, dann färben wir sie einfach wieder schwarz. Dadurch erhöht sich die Schwarzhöhe des Baumes um 1.
Einfügen: Was kann passieren? (3)
Ist der Onkel e dagegen schwarz, so erhalten wir Fall 2 und Fall 3:
d
c e
d
c e
Fall 2 Fall 3
Fall 2
Dieser Fall lässt sich durch Linksrotation um c auf Fall 3 reduzieren.
I
Schwarz-Höhe des linken Teilbaumes von d ändert das nicht.
I
Der bisherige Vaterknoten c wird dabei zum linken, roten Kind, das
eine Rot-Rot-Verletzung mit dem neuen Vater (c im rechten Bild)
hat. Diese Verletzung wird wie im Fall 3 behoben.
Einfügen: Was kann passieren? (4)
d
c e
bh(·) =x+1
x x
x
−→
c
d e bh(·) =x+1 x
x x
x
Fall 3
I
Zunächst rotieren wir um d nach rechts, wobei wir die Schwarz-Höhen im Auge behalten.
I
Um die Schwarz-Höhen der Kinder von c wieder in Einklang zu bringen, färben wir Knoten d rot. Da dessen nun linkes Kind ursprünglich am roten c hing, ist das unproblematisch.
I
Schlussendlich färben wir c schwarz. Wir haben wieder einen gültigen RBT, mit unveränderter Schwarzhöhe des Gesamtbaumes.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 17/41
Einfügen in einen RBT: Algorithmus, Teil 2
1 // B e h e b e e v e n t u e l l e Rot - Rot - V e r l e t z u n g mit V a t e r 2 // K n o t e n n o d e ist rot
3 v o i d r b t I n s F i x ( T r e e t , N o d e n o d e ) {
4 // s o l a n g e n o c h e i n e Rot - Rot - V e r l e t z u n g b e s t e h t 5 w h i l e ( n o d e . p a r e n t . c o l o r == RED ) {
6 if ( n o d e . p a r e n t == n o d e . p a r e n t . p a r e n t . l e f t ) { 7 // der von uns b e t r a c h t e t e F a l l
8 n o d e = l e f t A d j u s t ( t , n o d e ) ; 9 // n o d e j e t z t w e i t e r o b e n ?
10 // ( n o d e = n o d e . p a r e n t . p a r e n t im F a l l 1 von l e f t A d j u s t )
11 } e l s e {
12 // der d a z u s y m m e t r i s c h e r F a l l 13 n o d e = r i g h t A d j u s t ( t , n o d e ) ;
14 }
15 }
16 t . r o o t . c o l o r = B L A C K ; // W u r z e l b l e i b t s c h w a r z 17 }
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 18/41
Einfügen in einen RBT: Algorithmus Teil 3
1 N o d e l e f t A d j u s t ( T r e e t , N o d e n o d e ) { 2 N o d e u n c l e = n o d e . p a r e n t . p a r e n t . r i g h t ; 3 if ( u n c l e . c o l o r == RED ) { // F a l l 1
4 n o d e . p a r e n t . p a r e n t . c o l o r = RED ; // G r o s s v a t e r 5 n o d e . p a r e n t . c o l o r = B L A C K ; // V a t e r
6 u n c l e . c o l o r = B L A C K ; // O n k e l
7 r e t u r n n o d e . p a r e n t . p a r e n t ; // p r u e f e Rot - Rot w e i t e r o b e n
8 } e l s e { // F a l l 2 und 3
9 if ( n o d e == n o d e . p a r e n t . r i g h t ) { // F a l l 2 10 // d i e s e r K n o t e n w i r d das linke , r o t e K i n d : 11 n o d e = n o d e . p a r e n t ;
12 l e f t R o t a t e ( t , n o d e ) ;
13 } // F a l l 3
14 r i g h t R o t a t e ( t , n o d e . p a r e n t . p a r e n t ) ; 15 n o d e . p a r e n t . c o l o r = B L A C K ;
16 n o d e . p a r e n t . r i g h t . c o l o r = RED ;
17 r e t u r n n o d e ; // fertig , n o d e . p a r e n t . c o l o r == B L A C K
18 }
19 }
Einfügen in einen RBT: Analyse
Zeitkomplexität Einfügen
Die Worst-Case Laufzeit von
rbtInsfür einen Rot-Schwarz-Baum mit n inneren Knoten ist O(log n).
Beweisskizze:
I
Die Worst-Case Laufzeit von
bstInsist O(log n).
I
Die Schleife in
rbtInsFixwird nur wiederholt wenn Fall 1 auftrittt.
Dann steigt der Zeiger
nodezwei Ebenen im Baum auf.
I
Die maximal Anzahl der Schleifen ist damit O(log n).
I
Es werden höchstens zwei Rotationen ausgeführt, da die Schleife in
rbtInsFix
terminiert, wenn Fall 2 oder 3 auftritt. (Fall 1 involviert keine Rotationen.)
I
Ergo: Gesamtanzahl der Rotationen ist konstant und eine Rotation läuft in O(1).
I
Somit benötigt
rbtInseine Gesamtzeit O(log n).
Löschen in Rot-Schwarz Bäumen
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 21/41
Wiederholung: Löschen im BST / Strategie
Löschen
Um Knoten
nodeaus dem BST zu löschen, verfahren wir folgendermassen:
Fall 1:
nodehat keine Kinder:
Ersetze im Vaterknoten von
nodeden Zeiger auf
nodedurch
nullFall 2:
nodehat ein Kind:
Wir schneiden
nodeaus, indem wir den Vater und das Kind direkt miteinander verbinden (den Teilbaum ersetzen).
Fall 3:
nodehat zwei Kinder:
Wir finden den Nachfolger von
node, entfernen ihn aus seiner ursprünglichen Position und tauschen
nodegegen den Nachfolger.
I
Anmerkung: Der Nachfolger hat höchstens ein Kind.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 22/41
Wiederholung: Löschen im BST / (k)ein Kind
5
3 12
16 20 17 31 6
15
10 14
5
3 12
16 20 17 31 6
15
10
5
3 20
17 31 6
15
10 14 12
16 5
3 20
17 31 6
15
10 14 12
Wiederholung: Löschen im BST / zwei Kinder
3 20
17 31
6 15
10 14 12
16 5
3 20
17 31
6 15
10 14 12
16 5
3 20
17 31 6
15
10 14 12
16
Löschen im RBT: Strategie (1)
Löschen
Um die Farbbedingungen aufrecht zu erhalten, müssen wir unser altes Löschverfahren für BSTs ergänzen:
(1) Löschen wir einen roten Knoten, bleibt alles beim alten:
1. Im Baum werden keine Schwarzhöhen geändert 2. Es entstehen keine benachbarten roten Knoten 3. Die Wurzel bleibt schwarz.
Dieser Fall ist harmlos.
(2) Löschen wir hingegen einen schwarzen Knoten, so ändert sich der Schwarzwert des Pfades, der zuvor den gelöschten Knoten enthalten hat.
Diese Schwarz-Höhen-Verletzung muss repariert werden.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 25/41
Löschen im RBT: Strategie (2)
Löschen
Für den Fall, dass
nodezwei Kinder hat:
1. Wir finden den Nachfolger von
node2. Wir entfernen den Nachfolger (mittels unserer alten Prozedur
rbtDel
) aus seiner ursprünglichen Position
3. Wir beheben dabei die möglich auftretende Farbverletzung 4. Wir ersetzen
nodedurch den Nachfolger, und
5. übernehmen dabei die möglicherweise neue Farbe von
node. Der Baum bleibt ein gültiger RBT.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 26/41
Wiederholung: Löschen im BST / Algorithmus (VL-10)
1 // E n t f e r n t n o d e aus dem B a u m .
2 // D a n a c h k a n n n o d e ggf . aus S p e i c h e r e n t f e r n t w e r d e n 3 v o i d b s t D e l ( T r e e t , N o d e n o d e ) {
4 if ( n o d e . l e f t && n o d e . r i g h t ) { // z w e i K i n d e r 5 N o d e tmp = b s t M i n ( n o d e . r i g h t ) ; // f i n d e N a c h f o l g e r 6 b s t D e l ( t , tmp ) ; // l o e s c h e N a c h f o l g e r
7 b s t S w a p ( t , node , tmp ) ;
8 } e l s e if ( n o d e . l e f t ) { // ein Kind , l i n k s 9 b s t R e p l a c e ( t , node , n o d e . l e f t ) ;
10 } e l s e { // ein o d e r k e i n K i n d ( n o d e . r i g h t == n u l l ) 11 b s t R e p l a c e ( t , node , n o d e . r i g h t ) ;
12 }
13 }
Wiederholung: Löschen im BST / Variante von VL-10
1 // E n t f e r n t n o d e aus dem B a u m .
2 // D a n a c h k a n n n o d e ggf . aus S p e i c h e r e n t f e r n t w e r d e n 3 v o i d b s t D e l ( T r e e t , N o d e n o d e ) {
4 if ( n o d e . l e f t && n o d e . r i g h t ) { // z w e i K i n d e r 5 N o d e tmp = b s t M i n ( n o d e . r i g h t ) ; // f i n d e N a c h f o l g e r 6 b s t D e l ( t , tmp ) ; // l o e s c h e N a c h f o l g e r
7 b s t S w a p ( t , node , tmp ) ;
8 } e l s e { // ein Kind , o d e r k e i n K i n d 9 N o d e c h i l d ; // H i l f s v a r i a b l e
10 if ( n o d e . l e f t ) c h i l d = n o d e . l e f t ; // K i n d ist l i n k s 11 e l s e if ( n o d e . r i g h t ) c h i l d = n o d e . r i g h t ; // r e c h t s 12 e l s e c h i l d = n u l l ; // k e i n K i n d
13 b s t R e p l a c e ( t , node , c h i l d ) ;
14 }
15 }
Löschen im RBT: Algorithmus, Teil 1
1 // E n t f e r n t n o d e aus dem B a u m . 2 v o i d r b t D e l ( T r e e t , N o d e n o d e ) {
3 if ( n o d e . l e f t && n o d e . r i g h t ) { // z w e i K i n d e r
4 N o d e tmp = b s t M i n ( n o d e . r i g h t ) ; // f i n d e N a c h f o l g e r 5 r b t D e l ( t , tmp ) ; // l o e s c h e N a c h f o l g e r
6 b s t S w a p ( t , node , tmp ) ; // e r s e t z e n o d e d u r c h N f o l g e r 7 tmp . c o l o r = n o d e . c o l o r ; // u e b e r n i m m die F a r b e 8 } e l s e { // ein Kind , o d e r k e i n K i n d
9 N o d e c h i l d ; // H i l f s v a r i a b l e
10 if ( n o d e . l e f t ) c h i l d = n o d e . l e f t ; // K i n d ist l i n k s 11 e l s e if ( n o d e . r i g h t ) c h i l d = n o d e . r i g h t ; // r e c h t s 12 e l s e c h i l d = n u l l ; // k e i n K i n d
13 r b t D e l F i x ( t , node , c h i l d ) ; 14 b s t R e p l a c e ( t , node , c h i l d ) ;
15 }
16 }
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 29/41
Löschen im RBT: Beispiel 1
23 13
7 18
17
30
28 35
38
23 13
7 18
17
30
28 38
rbtDel(t, 35)
I
Wie beim BST tritt der rechte Teilbaum von 35 an dessen Stelle.
I
Da einer der beiden Knoten rot ist, kann vorher die Farbe der Knoten einfach vertauscht werden. Dazu färben wir Knoten 38 schwarz (Knoten 35 wird sowieso gelöscht).
I
Wäre auch 38 bereits schwarz gewesen, hätten wir die Verletzung aufwändiger weiter oben beheben müssen, indem 35 seinen Schwarzwert in Richtung Wurzel „weitergibt“.
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 30/41
Löschen im RBT – Beispiel 2
23 13
7 18
17
30
28 35
38
23 13
7 18
17
30
28 38
35 rbtDel(t, 30)
1.
2.
I
Da Knoten 30 zwei Kinder hat, finden wir zuerst den Nachfolger.
I
Lösche 35 derart, dass die RBT-Eigenschaft erhalten bleibt (siehe voriges Beispiel).
I
Ersetze 30 durch freie 35, wobei die Farbe von 30 übernommen wird.
Löschen im RBT: Algorithmus, Teil 2
1 // n o d e s o l l g e l o e s c h t werden , c h i l d ist e i n z i g e s K i n d 2 // ( bzw . n o d e hat k e i n e Kinder , und c h i l d == n u l l ) ; 3 // Ist n o d e rot , so ist n i c h t s zu tun ; s o n s t s u c h e n wir 4 // e i n e n r o t e n Knoten , der d u r c h U m f a e r b e n auf s c h w a r z 5 // die s c h w a r z e F a r b e von n o d e u e b e r n i m m t
6 v o i d r b t D e l F i x ( T r e e t , N o d e node , N o d e c h i l d ) { 7 if ( n o d e . c o l o r == RED ) r e t u r n ;
8 if ( c h i l d != n u l l && c h i l d . c o l o r == RED ) { 9 c h i l d . c o l o r = B L A C K ;
10 } e l s e {
11 N o d e s e a r c h P o s = n o d e ;
12 // s o l a n g e S c h w a r z w e r t n i c h t e i n g e f u e g t w e r d e n k a n n 13 w h i l e ( s e a r c h P o s . p a r e n t && s e a r c h P o s . c o l o r == B L A C K ) { 14 if ( s e a r c h P o s == s e a r c h P o s . p a r e n t . l e f t ) // l i n k e s K i n d 15 s e a r c h P o s = d e l L e f t A d j u s t ( t , s e a r c h P o s ) ;
16 e l s e // r e c h t e s K i n d
17 s e a r c h P o s = d e l R i g h t A d j u s t ( t , s e a r c h P o s ) ;
18 }
19 s e a r c h P o s . c o l o r = B L A C K ;
20 }
21 }
Löschen im RBT: Algorithmus, Teil 3a
1 // E r l e i c h t e r t n o d e um e i n e n S c h w a r z w e r t , 2 // w o b e i n o d e das l i n k e K i n d ist .
3 N o d e d e l L e f t A d j u s t ( T r e e t , N o d e n o d e ) {
4 // b r o t h e r e x i s t i e r t i m m e r w e g e n S c h w a r z h o e h e 5 N o d e b r o t h e r = n o d e . p a r e n t . r i g h t ;
6 if ( b r o t h e r . c o l o r == RED ) { 7 // F a l l 1: R e d u k t i o n auf 2 ,3 ,4 8 b r o t h e r . c o l o r = B L A C K ;
9 n o d e . p a r e n t . c o l o r = RED ; // V a t e r 10 l e f t R o t a t e ( t , n o d e . p a r e n t ) ;
11 b r o t h e r = n o d e . p a r e n t . r i g h t ; // nun B r u d e r von n o d e
12 }
→ wird auf nächster Seite fortgesetzt
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 33/41
Löschen im RBT: Algorithmus, Teil 3b
12 if ( b r o t h e r . l e f t . c o l o r == B L A C K &&
13 b r o t h e r . r i g h t . c o l o r == B L A C K ) { // F a l l 2 14 b r o t h e r . c o l o r = RED ;
15 r e t u r n n o d e . p a r e n t ; // Doppel - s c h w a r z w e i t e r o b e n ...
16 } e l s e { // F a l l 3 und 4
17 if ( b r o t h e r . r i g h t . c o l o r == B L A C K ) // F a l l 3 18 b r o t h e r . l e f t . c o l o r = B L A C K ;
19 b r o t h e r . c o l o r = RED ; 20 r i g h t R o t a t e ( t , b r o t h e r ) ;
21 b r o t h e r = n o d e . p a r e n t . r i g h t ; // nun B r u d e r von n o d e
22 } // F a l l 4
23 b r o t h e r . c o l o r = n o d e . p a r e n t . c o l o r ; 24 n o d e . p a r e n t . c o l o r = B L A C K ;
25 b r o t h e r . r i g h t . c o l o r = B L A C K ; 26 l e f t R o t a t e ( t , n o d e . p a r e n t ) ; 27 r e t u r n t . r o o t ; // F e r t i g .
28 }
29 }
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 34/41
Der Löschalgorithmus: Fall 1
Fall 1:
(Reduktion auf Fall 2, 3 oder 4)sPos brother
−→ −→
sPos
neuer brother
Der Löschalgorithmus: Fall 2
Fall 2:
c
sPos brother
−→
c neuer
sPos
Der Löschalgorithmus: Fall 3
Fall 3:
(Reduktion auf Fall 4)c
sPos brother
−→
c
−→
c sPos
neuer brother
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 37/41
Der Löschalgorithmus: Fall 4
Fall 4:
c
d
sPos brother
−→
c d
−→
c
d
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 38/41
Löschen im RBT: Analyse
Zeitkomplexität Löschen
Die Worst-Case Laufzeit von
rbtDelfür einen Rot-Schwarz-Baum mit n inneren Knoten ist O(log n).
Beweisskizze:
I
Die Laufzeit von
rbtDelohne Aufrufe von
rbtDelFixist O(log n).
I
Die Fälle 2, 3, und 4 brauchen höchstens drei Rotationen und eine konstante Anzahl Farbänderungen.
I
Die Schleife in
rbtDelFixwird nur wiederholt wenn Fall 2 auftrittt.
Dann steigt der Zeiger
nodeeine Ebene im Baum hinauf.
I
Die maximale Anzahl der Schleifen ist damit O(log n).
I
Somit benötigt
rbtDeleine Gesamtzeit O(log n).
Komplexität der RBT-Operationen
Operation Zeit
bstSearch
Θ(h)
bstSucc
Θ(h)
bstMin
Θ(h)
bstIns
Θ(h)
bstDel
Θ(h)
Operation Zeit
rbtIns
Θ(log n)
rbtDel
Θ(log n)
Alle anderen Operationen wie beim BST, wobei h = log n.
Zusammengefasst:
Die Laufzeit für alle Operationen ist logarithmisch in der Grösse des
Rot-Schwarz-Baumes.
Organisatorisches
• Nächste Vorlesung:
Dienstag, Mai 30, 16:15–17:45 Uhr, Aula 1 (Mai 25 = Feiertag; keine Vorlesung)
• Webseite: http://algo.rwth-aachen.de/Lehre/SS17/DSA.php
DSAL/SS 2017 VL-11: Rot-Schwarz Bäume 41/41