Rot-Schwarz-Bäume

Werbung
1
Algorithmen und Datenstrukturen
Wintersemester 2016/17
14. Vorlesung
Rot-Schwarz-Bäume
Prof. Dr. Alexander Wolff
Lehrstuhl für Informatik I
2
Dynamische Menge
verwaltet Elemente einer
sich ändernden Menge M
Abstrakter Datentyp
ptr Insert(key k , info i )
Delete(ptr x )
ptr Search(key k )
ptr Minimum()
ptr Maximum()
ptr Predecessor(ptr x )
ptr Successor(ptr x )
Funktionalität
Änderungen








Anfragen







Implementierung: je nachdem...
3-1
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
12
6
19
9
8
14
13
17
3-2
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
12
6
19
9
8
14
13
17
3-3
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
12
6
19
9
8
14
13
17
3-4
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
12
Ziel:
6
19
9
8
14
13
17
3-5
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
12
6
19
9
8
14
13
17
3-6
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
⇒ h ∈ O (log n)
12
6
19
9
8
14
13
17
3-7
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
⇒ h ∈ O (log n)
12
6
19
9
14
Binärer-Suchbaum-Eigenschaft:
8
13
17
3-8
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
⇒ h ∈ O (log n)
12
6
19
9
14
Binärer-Suchbaum-Eigenschaft:
Für jeden Knoten v gilt:
8
13
17
3-9
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
⇒ h ∈ O (log n)
12
6
19
9
14
Binärer-Suchbaum-Eigenschaft:
Für jeden Knoten v gilt:
8
13
17
alle Knoten im linken Teilbaum von v haben Schlüssel ≤ v .key
3-1
Binäre Suchbäume
Satz.
Binäre Suchbäume implementieren alle
dynamische-Menge-Operationen in O (h) Zeit,
wobei h die momentane Höhe des Baums ist.
Aber:
Im schlechtesten Fall gilt h ∈ Θ (n).
Ziel:
Suchbäume balancieren!
⇒ h ∈ O (log n)
12
6
19
9
14
Binärer-Suchbaum-Eigenschaft:
Für jeden Knoten v gilt:
8
13
17
alle Knoten im linken Teilbaum von v haben Schlüssel ≤ v .key
≥
rechten
(c) Rhein-Zeitung, 2.8.1998 4 - 1
Balaciermethoden
nach Gewicht
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
(c) Rhein-Zeitung, 2.8.1998 4 - 2
Balaciermethoden
nach Gewicht
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
(c) Rhein-Zeitung, 2.8.1998 4 - 3
Balaciermethoden
nach Gewicht
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
nach Grad
alle Blätter haben dieselbe Tiefe, aber innere
Knoten können verschieden viele Kinder haben.
(c) Rhein-Zeitung, 2.8.1998 4 - 4
Balaciermethoden
nach Gewicht
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
nach Grad
alle Blätter haben dieselbe Tiefe, aber innere
Knoten können verschieden viele Kinder haben.
nach Knotenfarbe
jeder Knoten ist entw. gut“ oder schlecht“; der Anteil
”
”
schlechter Knoten darf in keinem Teilbaum zu groß sein.
(c) Rhein-Zeitung, 2.8.1998 4 - 5
Balaciermethoden
Beispiele
nach Gewicht
BB [α]-Bäume
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
AVL-Bäume?
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
nach Grad
(2, 3)-Bäume
alle Blätter haben dieselbe Tiefe, aber innere
Knoten können verschieden viele Kinder haben.
Rot-Schwarz-Bäume
nach Knotenfarbe
jeder Knoten ist entw. gut“ oder schlecht“; der Anteil
”
”
schlechter Knoten darf in keinem Teilbaum zu groß sein.
(c) Rhein-Zeitung, 2.8.1998 4 - 6
Balaciermethoden
Beispiele
nach Gewicht
BB [α]-Bäume
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
AVL-Bäume?
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
?) Georgi M. Adelson-Velski & Jewgeni M. Landis, Doklady Akademii Nauk SSSR, 1962
nach Grad
(2, 3)-Bäume
alle Blätter haben dieselbe Tiefe, aber innere
Knoten können verschieden viele Kinder haben. 1922–2014 1921–1997
Rot-Schwarz-Bäume
nach Knotenfarbe
jeder Knoten ist entw. gut“ oder schlecht“; der Anteil
”
”
schlechter Knoten darf in keinem Teilbaum zu groß sein.
Foto von GAV: The Eugene Dynkin Collection, Cornell University. Foto von JL: Konrad Jacobs / wikipedia
(c) Rhein-Zeitung, 2.8.1998 4 - 7
Balaciermethoden
Beispiele
nach Gewicht
BB [α]-Bäume
für jeden Knoten ist das Gewicht
(= Anzahl der Knoten) von linkem
u. rechtem Teilbaum ungefähr gleich.
nach Höhe
AVL-Bäume?
für jeden Knoten ist die Höhe
von linkem und rechtem Teilbaum ungefähr gleich.
?) Georgi M. Adelson-Velski & Jewgeni M. Landis, Doklady Akademii Nauk SSSR, 1962
nach Grad
(2, 3)-Bäume
alle Blätter haben dieselbe Tiefe, aber innere
Knoten können verschieden viele Kinder haben. 1922–2014 1921–1997
Rot-Schwarz-Bäume
nach Knotenfarbe
jeder Knoten ist entw. gut“ oder schlecht“; der Anteil
”
”
schlechter Knoten darf in keinem Teilbaum zu groß sein.
Foto von GAV: The Eugene Dynkin Collection, Cornell University. Foto von JL: Konrad Jacobs / wikipedia
5-1
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
5-2
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
(E1) Jeder Knoten ist entweder
rot oder schwarz.
5-3
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
nil
19
14
nil
24
17
nil
nil
nil
nil
nil
5-4
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
19
14
(E2) Die Wurzel ist schwarz. nil nil
24
17
nil
nil
nil
nil
nil
5-5
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
19
14
(E2) Die Wurzel ist schwarz. nil nil
(E3) Alle Blätter sind schwarz.
24
17
nil
nil
nil
nil
nil
5-6
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
19
14
(E2) Die Wurzel ist schwarz. nil nil
(E3) Alle Blätter sind schwarz.
(E4) Wenn ein Knoten rot ist,
sind seine beiden Kinder schwarz.
24
17
nil
nil
nil
nil
nil
5-7
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
(E2) Die Wurzel ist schwarz. nil nil
19
14
24
(E3) Alle Blätter sind schwarz.
nil
17 nil nil
(E4) Wenn ein Knoten rot ist,
sind seine beiden Kinder schwarz.
nil nil
(E5) Für jeden Teilbaum gilt: alle Wurzel-Blatt-Pfade enthalten
dieselbe Anzahl schwarzer Knoten.
5-8
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
(E2) Die Wurzel ist schwarz. nil nil
19
14
24
(E3) Alle Blätter sind schwarz.
nil
17 nil nil
(E4) Wenn ein Knoten rot ist,
sind seine beiden Kinder schwarz.
nil nil
(E5) Für jeden Teilbaum gilt: alle Wurzel-Blatt-Pfade enthalten
dieselbe Anzahl schwarzer Knoten.
Aus (E4) folgt:
5-9
Rot-Schwarz-Bäume: Eigenschaften
Rot-Schwarz-Bäume sind binäre Suchbäume mit folgenden
Rot-Schwarz-Eigenschaften:
12
(E1) Jeder Knoten ist entweder 6
rot oder schwarz.
(E2) Die Wurzel ist schwarz. nil nil
19
14
24
(E3) Alle Blätter sind schwarz.
nil
17 nil nil
(E4) Wenn ein Knoten rot ist,
sind seine beiden Kinder schwarz.
nil nil
(E5) Für jeden Teilbaum gilt: alle Wurzel-Blatt-Pfade enthalten
dieselbe Anzahl schwarzer Knoten.
Aus (E4) folgt: Auf keinem Wurzel-Blatt-Pfad folgen zwei rote
Knoten direkt auf einander.
6-1
Technisches Detail
12
6
nil
19
14
nil
24
17
nil
nil
nil
nil
nil
6-2
Technisches Detail
Node
Key key
Node left
Node right
Node p
12
6
nil
19
14
nil
24
17
nil
nil
nil
nil
nil
6-3
Technisches Detail
Node
Key key
Node left
Node right
Node p
12
6
nil
RBNode
Color color
19
14
nil
24
17
nil
nil
nil
nil
nil
6-4
Technisches Detail
T.root
Node
Key key
Node left
Node right
Node p
12
6
nil
RBNode
T.root
Color color
19
14
nil
24
17
nil
nil
nil
nil
nil
6-5
Technisches Detail
T.root
Node
Key key
Node left
Node right
Node p
12
6
nil
RBNode
T.root , T.nil
Color color
19
14
nil
17
nil
nil
Dummy-Knoten (engl. sentinel)
T .nil
24
nil
nil
nil
6-6
Technisches Detail
T.root
Node
Key key
Node left
Node right
Node p
12
6
nil
RBNode
T.root , T.nil
Color color
19
14
nil
17
nil
nil
Dummy-Knoten (engl. sentinel)
T .nil
24
nil
nil
nil
6-7
Technisches Detail
Node
Key key
Node left
Node right
Node p
T.root
12
6
19
14
RBNode
T.root , T.nil
Color color
Dummy-Knoten (engl. sentinel)
24
17
T .nil
6-8
Technisches Detail
Node
Key key
Node left
Node right
Node p
T.root.p
T.root
12
6
19
14
RBNode
T.root , T.nil
Color color
Dummy-Knoten (engl. sentinel)
24
17
T .nil
6-9
Technisches Detail
Node
Key key
Node left
Node right
Node p
T.root.p
T.root
12
6
19
14
RBNode
T.root , T.nil
Color color
Dummy-Knoten (engl. sentinel)
24
17
T .nil
Zweck: um Baum-Operationen prägnanter aufschreiben zu
können.
6-1
Technisches Detail
Node
Key key
Node left
Node right
Node p
T.root.p
T.root
12
6
19
14
RBNode
T.root , T.nil
Color color
Dummy-Knoten (engl. sentinel)
24
17
T .nil
Zweck: um Baum-Operationen prägnanter aufschreiben zu
können. (Wir zeichnen den Dummy-Knoten i.A. nicht.)
6-1
Technisches Detail
Node
Key key
Node left
Node right
Node p
T.root
12
6
19
14
RBNode
T.root , T.nil
Color color
24
17
Zweck: um Baum-Operationen prägnanter aufschreiben zu
können. (Wir zeichnen den Dummy-Knoten i.A. nicht.)
(Schwarz-) Höhe
Definition: Die Länge eines Pfades ist
die Anz. seiner Kanten.
7-1
12
6
19
14
24
17
(Schwarz-) Höhe
7-2
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
(Schwarz-) Höhe
7-3
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
Beispiel:
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
(Schwarz-) Höhe
7-4
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
(Schwarz-) Höhe
7-5
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Definition:0 Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
Beispiel:
die Anz. der schwarzen Knoten (ohne v ) auf dem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
(Schwarz-) Höhe
7-6
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Definition:0 Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
Beispiel:
die Anz. der schwarzen Knoten (ohne v ) auf dem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
Beispiel:
12“ hat Höhe 4 (!)
”
(Schwarz-) Höhe
7-7
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
Beispiel:
12“ hat Höhe 4 (!)
”
(Schwarz-) Höhe
7-8
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
wohldefiniert
wg. (E5)
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
Beispiel:
12“ hat Höhe 4 (!)
”
(Schwarz-) Höhe
7-9
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
wohldefiniert
wg. (E5)
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
Beispiel:
12“ hat Höhe 4 (!) und Schwarz-Höhe 2.
”
(Schwarz-) Höhe
7-1
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
wohldefiniert
wg. (E5)
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
12“ hat Höhe 4 (!) und Schwarz-Höhe 2.
”
Folgerung: v Knoten ⇒ sHöhe(v ) ≤ Höhe(v )
Beispiel:
(Schwarz-) Höhe
7-1
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
wohldefiniert
wg. (E5)
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
12“ hat Höhe 4 (!) und Schwarz-Höhe 2.
”
Folgerung: v Knoten ⇒ sHöhe(v ) ≤ Höhe(v ) ≤
Beispiel:
(Schwarz-) Höhe
7-1
12
6
19
Definition: Die Länge eines Pfades ist
14
24
die Anz. seiner Kanten.
17
Definition: Sei B ein Baum.
Knoten u ist unter Knoten v , wenn u in dem
Teilbaum Bv von B mit Wurzel v enthalten ist.
17“ ist unter 19“, 14“ ist nicht unter 6“.
”
”
”
”
Definition: Die Höhe eines Knotens v ist die Länge eines
längsten Pfads von v zu einem Blatt unter v .
Beispiel:
wohldefiniert
wg. (E5)
Definition: Die Schwarz-Höhe sHöhe(v ) eines Knotens v ist
die Anz. der schwarzen Knoten (ohne v ) auf jedem
längsten Pfad zu einem Blatt (inkl. Blatt) in Bv .
12“ hat Höhe 4 (!) und Schwarz-Höhe 2.
”
Folgerung: v Knoten ⇒ sHöhe(v ) ≤ Höhe(v ) ≤ 2 · sHöhe(v ).
Beispiel:
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
8-3
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
v
Bv
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
8-4
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
8-5
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0.
8-6
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil
8-7
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
8-8
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
8-9
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0.
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 =
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 =
sHöhe der Kinder von v ist mind.
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 =
|
{z
}
sHöhe der Kinder von v ist mind.
Anz. innerer Knoten unter
einem Kind von v
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 = 2sHöhe(v ) − 1.
|
{z
}
sHöhe der Kinder von v ist mind.
Anz. innerer Knoten unter
einem Kind von v
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 = 2sHöhe(v ) − 1.
|
{z
}
sHöhe der Kinder von v ist mind.
Anz. innerer Knoten unter
einem Kind von v
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
Beweis durch vollständige Induktion über Höhe(v ).
Höhe(v ) = 0. Dann Bv = B .nil und sHöhe(v ) = 0.
Bv hat 0 = 20 −1 innere Knoten.
Höhe(v ) > 0. Beide Kinder von v haben Höhe < Höhe(v ).
⇒ können Ind.-Annahme anwenden.
⇒ # innere Knoten von Bv ist mind.
2 · (2sHöhe(v )−1 − 1) + 1 = 2sHöhe(v ) − 1.
|
{z
}
sHöhe der Kinder von v ist mind.
Anz. innerer Knoten unter
einem Kind von v
8-1
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt:
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
Also:
Rot-Schwarz-Bäume sind balanciert!
8-2
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
Also:
Rot-Schwarz-Bäume sind balanciert! Fertig?!
8-3
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
Also:
Rot-Schwarz-Bäume sind balanciert! Fertig?!
Nee:
8-3
Höhe ∈ Θ(log n)!!
Lemma. Ein Rot-Schwarz-Baum B mit n inneren Knoten hat
Höhe ≤ 2 log2 (n + 1).
Beweis.
Behauptung: Für jeden Knoten v von B gilt:
Bv hat ≥ 2sHöhe(v ) − 1 innere Knoten.
v := B .root ⇒ # innere Knoten(B ) ≥ 2sHöhe(B ) − 1.
|
{z
}
n
⇒ sHöhe(B ) ≤ log2 (n + 1)
Wegen R-S-Eig. (E4) gilt: Höhe(B ) ≤ 2 sHöhe(B ).
⇒ Höhe(B ) ≤ 2 log2 (n + 1)
Also:
Rot-Schwarz-Bäume sind balanciert! Fertig?!
Nee: Insert & Delete können R-S-Eig. verletzen!
9-1
Einfügen
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
9
14
13
21
17
9-2
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
9
14
13
21
17
9-3
Einfügen
x
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
9
14
13
21
17
9-4
Einfügen
x
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
y
19
9
14
13
21
17
9-5
Einfügen
y
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
12
x
19
9
14
13
21
17
9-6
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
x
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
12
y
19
9
14
13
21
17
9-7
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
6 x
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
12
y
19
9
14
13
21
17
9-8
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6 x
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
y
9
14
13
21
17
9-9
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
x == nil
19
y
9
14
13
21
17
Node(Key k , Node par )
key = k
p = par
right = left = T .nil
9-1
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
x == nil
19
y
9
14
p
11
13
21
17
z
Node(Key k , Node par )
key = k
p = par
right = left = T .nil
9-1
Einfügen
Insert(11)
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
x == nil
19
y
9
14
p
11
13
21
17
z
Node(Key k , Node par )
key = k
p = par
right = left = T .nil
9-1
Einfügen
RB
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
9
14
11
13
21
17
z
Node(Key k , Node par )
key = k
p = par
right = left = T .nil
9-1
Einfügen
RB
Node Insert(key k )
y = T .nil
x = root
while x 6= T .nil do
y =x
if k < x .key then
x = x .left
else x = x .right
12
6
3
z = new Node(k , y )
if y == T .nil then root = z
else
if k < y .key then y .left = z
else
y .right = z
return z
19
9
14
11
13
21
17
z
Node(Key k , Node par )
key = k
p = par
right = left = T .nil
9-1
Einfügen
RB RB
Node Insert(key k )
12
y = T .nil
x = root
6
19
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
color = c
return z
9-1
Einfügen
RB RB
Node Insert(key k )
12
y = T .nil
Widerspruch
x = root
6
19
zu Eig. (E4)
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
color = c
return z
9-1
Einfügen
RB RB
Node Insert(key k )
12
y = T .nil
Widerspruch
x = root
6
19
zu Eig. (E4)
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
RBInsertFixup(z )
return z
color = c
9-1
Einfügen
Laufzeit?
(ohne RBInsertFixup)
RB RB
Node Insert(key k )
12
y = T .nil
Widerspruch
x = root
6
19
zu Eig. (E4)
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
RBInsertFixup(z )
return z
color = c
9-1
Einfügen
Laufzeit?
(ohne RBInsertFixup)
O (h )
RB RB
Node Insert(key k )
12
y = T .nil
Widerspruch
x = root
6
19
zu Eig. (E4)
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
RBInsertFixup(z )
return z
color = c
9-1
Einfügen
Laufzeit?
(ohne RBInsertFixup)
O (h) = O (log n)
RB RB
Node Insert(key k )
12
y = T .nil
Widerspruch
x = root
6
19
zu Eig. (E4)
while x 6= T .nil do
y =x
3
9
14
21
if k < x .key then
x = x .left
11 13 17
z
else x = x .right
RB
z = new Node(k , y ) , red )
Node(Key k , Node par )
key = k
if y == T .nil then root = z
p = par
else
right = left = T .nil
if k < y .key then y .left = z
RBNode(. . . , Color c )
else
y .right = z
super(k, par )
RBInsertFixup(z )
return z
color = c
10 -
Exkurs: Rotationen
y
RightRotate(y )
x
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
x
y
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
y
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
y
x
y
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
Also:
y
x
y
Binärer-Suchbaum-Eig. bleibt beim Rotieren erhalten!
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
Also:
y
x
y
Binärer-Suchbaum-Eig. bleibt beim Rotieren erhalten!
Aufgabe: Schreiben Sie Pseudocode für LeftRotate(x )!
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
Also:
y
x
y
Binärer-Suchbaum-Eig. bleibt beim Rotieren erhalten!
Aufgabe: Schreiben Sie Pseudocode für LeftRotate(x )!
Laufzeit:
10 -
Exkurs: Rotationen
y
x
RightRotate(y )
y
x
LeftRotate(x )
x
Also:
y
x
y
Binärer-Suchbaum-Eig. bleibt beim Rotieren erhalten!
Aufgabe: Schreiben Sie Pseudocode für LeftRotate(x )!
Laufzeit: O (1).
11 -
RBInsertFixup(Node z)
while z .p .color == red do
if z .p == z .p .p .left then
// Tante von z
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )
11
z .p .p
2
1 z .p
z
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
5
4
y
7
8
14
15
11 -
RBInsertFixup(Node z)
11
2
z .p .p
while z .p .color == red do
if z .p == z .p .p .left then
1 z .p
7
// Tante von z
y = z .p .p .right
z
5
8
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
11 -
RBInsertFixup(Node z)
11
2
z .p .p
while z .p .color == red do
if z .p == z .p .p .left then
y
1 z .p
7
// Tante von z
y = z .p .p .right
z
5
8
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
11
else
if z == z .p .right then
z
2
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
14
15
14
15
11 -
RBInsertFixup(Node z)
11
2
z .p .p
while z .p .color == red do
if z .p == z .p .p .left then
y
1 z .p
7
// Tante von z
y = z .p .p .right
z
5
8
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
z .p .p 11
else
if z == z .p .right then
z
2 z .p
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
14
15
y
14
15
11 -
RBInsertFixup(Node z)
while z .p .color == red do
if z .p == z .p .p .left then
// Tante von z
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
z .p .p 11
else
if z == z .p .right then
z
2 z .p
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
11 -
RBInsertFixup(Node z)
while z .p .color == red do
if z .p == z .p .p .left then
// Tante von z
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
z .p .p 11
else
if z == z .p .right then
z
2 z .p
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
11 -
RBInsertFixup(Node z)
Fall 2
while z .p .color == red do
if z .p == z .p .p .left then
// Tante von z
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
z .p .p 11
else
if z == z .p .right then
z
2 z .p
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
11 -
RBInsertFixup(Node z)
Fall 2
z .p .p 11
z .p 7
while z .p .color == red do
if z .p == z .p .p .left then
z 2
8
// Tante von z
y = z .p .p .right
1
5
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 1
z .p .p 11
else
if z == z .p .right then
z
2 z .p
z = z .p
1
7
LeftRotate(z )
z .p .color = black
5
8
z .p .p .color = red
RightRotate(z .p .p )
4
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
y
14
15
11 -
RBInsertFixup(Node z)
while z .p .color == red do
if z .p == z .p .p .left then
// Tante von z
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )
Fall 2
z .p .p 11
z .p 7
z 2
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
14
8
1
5
4
y
15
11 -
RBInsertFixup(Node z)
Fall 2
z .p .p 11
z .p 7
while z .p .color == red do
if z .p == z .p .p .left then
z 2
// Tante von z
y = z .p .p .right
1
5
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 3
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
8
15
11 -
RBInsertFixup(Node z)
Fall 2
z .p .p 11
z .p 7
while z .p .color == red do
if z .p == z .p .p .left then
z 2
8
// Tante von z
y = z .p .p .right
1
5
if y .color == red then
z .p .color = black
4
z .p .p .color = red
y .color = black
z = z .p .p
Fall 3
7
else
if z == z .p .right then
z 2
z = z .p
1
5
8
LeftRotate(z )
z .p .color = black
4
z .p .p .color = red
RightRotate(z .p .p )
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
y
14
15
11
14
15
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
• Falls z .p die Wurzel ist, dann ist z .p schwarz.
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
• Falls z .p die Wurzel ist, dann ist z .p schwarz.
• Falls R-S-Eig. verletzt sind, dann entweder (E2) oder (E4).
– Falls (E2) verletzt ist, dann weil z = root und z rot ist.
– Falls (E4) verletzt ist, dann weil z und z .p rot sind.
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
• Falls z .p die Wurzel ist, dann ist z .p schwarz.
• Falls R-S-Eig. verletzt sind, dann entweder (E2) oder (E4).
– Falls (E2) verletzt ist, dann weil z = root und z rot ist.
– Falls (E4) verletzt ist, dann weil z und z .p rot sind.
Zeige:
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
• Falls z .p die Wurzel ist, dann ist z .p schwarz.
• Falls R-S-Eig. verletzt sind, dann entweder (E2) oder (E4).
– Falls (E2) verletzt ist, dann weil z = root und z rot ist.
– Falls (E4) verletzt ist, dann weil z und z .p rot sind.
Zeige:
– Initialisierung
– Aufrechterhaltung
– Terminierung
12 -
Korrektheit
Zu zeigen: RBInsertFixup stellt R-S-Eigenschaft wieder her.
Schleifeninvariante (gültig am Anfang der while-Schleife)
• z ist rot.
• Falls z .p die Wurzel ist, dann ist z .p schwarz.
• Falls R-S-Eig. verletzt sind, dann entweder (E2) oder (E4).
– Falls (E2) verletzt ist, dann weil z = root und z rot ist.
– Falls (E4) verletzt ist, dann weil z und z .p rot sind.
Zeige:
– Initialisierung
– Aufrechterhaltung
– Terminierung
Viel Arbeit! Siehe [CLRS, Kapitel 13.3].
13 -
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
13 -
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (1)


o
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
13 -
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (1)
Klettert Baum zwei
Ebenen nach oben.


o
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
13 -
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (1)
Klettert Baum zwei
Ebenen nach oben.


o
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
Führt zum Abbruch
der while-Schleife.
Insgesamt:
– Fall 1 O (h) mal
– Fall 2 ≤ 1 mal
– Fall 3 ≤ 1 mal
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (1)
Klettert Baum zwei
Ebenen nach oben.


o
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
Führt zum Abbruch
der while-Schleife.
13 -
Insgesamt:
– Fall 1 O (h) mal
– Fall 2 ≤ 1 mal
– Fall 3 ≤ 1 mal
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (1)
Klettert Baum zwei
Ebenen nach oben.


o
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
Führt zum Abbruch
der while-Schleife.
13 -
Insgesamt:
– Fall 1 O (h) mal
– Fall 2 ≤ 1 mal
– Fall 3 ≤ 1 mal
Laufzeit RBInsertFixup
while z .p .color == red do
if z .p == z .p .p .left then
y = z .p .p .right
if y .color == red then
z .p .color = black
z .p .p .color = red
y .color = black
z = z .p .p
else
if z == z .p .right then
z = z .p
LeftRotate(z )
z .p .color = black
z .p .p .color = red
RightRotate(z .p .p )



O (log n) Umfärbungen
und ≤ 2 Rotationen
O (1)
Klettert Baum zwei
Ebenen nach oben.


o
13 -
O (1)
)
O (1)
else . . . // wie oben, aber re. & li. vertauscht
root.color = black
Führt zum Abbruch
der while-Schleife.
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
12
1. z hat kein li. Kind.
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
14
17
18
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
12
1. z hat kein li. Kind.
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
14
z
17
18
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
1. z hat kein li. Kind.
Setze z .right an die Stelle von z .
Lösche z .
12
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
14
z
17
18
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
1. z hat kein li. Kind.
Setze z .right an die Stelle von z .
Lösche z .
12
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
14
z
17
18
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
1. z hat kein li. Kind.
Setze z .right an die Stelle von z .
Lösche z .
12
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
14
Transplant(u, v )
if u.p == nil then root = v
else
if u == u.p.left then
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
z
17
18
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
1. z hat kein li. Kind.
Setze z .right an die Stelle von z .
Lösche z .
12
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
17
z
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
Lösche z .
12
6
19
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
17
z
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
Lösche z .
12
z 19
6
16
2. z hat kein re. Kind.
13
3. z hat zwei Kinder.
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
Lösche z .
12
16
2. z hat kein re. Kind.
symmetrisch!
3. z hat zwei Kinder.
z 19
6
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
Lösche z .
12
16
2. z hat kein re. Kind.
symmetrisch!
3. z hat zwei Kinder.
z 19
6
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
Lösche z .
12
z 19
6
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
3. z hat zwei Kinder.
16
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
z
if z .left == nil then
12
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
6
Lösche z .
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
3. z hat zwei Kinder.
19
16
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
z
if z .left == nil then
12
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
6
Lösche z .
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
3. z hat zwei Kinder.
Setze y = Successor(z )
Falls y .p 6= z , setze y .right
an die Stelle von y .
Setze y an die Stelle von z
19
16
y
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
z
if z .left == nil then
12
1. z hat kein li. Kind.
Transplant(z , z .right)
Setze z .right an die Stelle von z .
6
Lösche z .
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
3. z hat zwei Kinder.
Setze y = Successor(z )
Falls y .p 6= z , setze y .right
an die Stelle von y .
Setze y an die Stelle von z
19
16
y
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
z
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right) y 12
13
Setze z .right an die Stelle von z .
6
Lösche z .
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
3. z hat zwei Kinder.
Setze y = Successor(z )
Falls y .p 6= z , setze y .right
an die Stelle von y .
Setze y an die Stelle von z
19
16
y
13
17
14
18
Transplant(u, v )
if u.p == nil then root = v
Setze v
else
an die
if u == u.p.left then
Stelle
u.p.left = v
else u.p.right = v
if v 6= nil then v .p = u.p
von u .
14 -
Löschen in (farblosen) binären Suchbäumen
Sei z der zu löschende Knoten. Wir betrachten drei Fälle:
z
if z .left == nil then
1. z hat kein li. Kind.
Transplant(z , z .right) y 12
13
Setze z .right an die Stelle von z .
6
Lösche z .
else if z .right == nil then
2. z hat kein re. Kind.
Transplant(z , z .left)
symmetrisch!
19
16
y
y = Successor(z )
if y .p 6= z then
3. z hat zwei Kinder.
Transplant(y , y .right)
y .right = z .right
Setze y = Successor(z )
y .right.p = y
Falls y .p 6= z , setze y .right
Transplant(z , y )
an die Stelle von y .
Setze y an die Stelle von z y .left = z .left
y .left.p = y
13
14
17
18
15
Löschen (Übersicht)
Delete(Node z )
if z .left == nil then
// kein linkes Kind
Transplant(z , z .right)
else
if z .right == nil then // kein rechtes Kind
Transplant(z , z .left)
// zwei Kinder
else
y = Successor(z )
if y .p 6= z then
Transplant(y , y .right)
y .right = z .right
y .right.p = y
Transplant(z , y )
y .left = z .left
y .left.p = y
RBDelete(Node z)
y = z; origcolor = y .color
if z.left == T .nil then
x = z.right
RBTransplant(z, z.right)
else
if z.right == T .nil then
x = z.left
RBTransplant(z, z.left)
else
y = Successor(z)
origcolor = y .color
x = y .right
if y .p == z then x.p = y
else
RBTransplant(y , y .right)
y .right = z.right
y .right.p = y
RBTransplant(z, y )
y .left = z.left
y .left.p = y ; y .color = z.color
16 RBTransplant(u , v )
if u .p == T .nil then root = v
else
if u == u .p .left then
u .p .left = v
else u .p .right = v
if v 6= nil then v .p = u .p
RBDelete(Node z)
y = z; origcolor = y .color
if z.left == T .nil then
x = z.right
RBTransplant(z, z.right)
else
if z.right == T .nil then
x = z.left
RBTransplant(z, z.left)
else
y = Successor(z)
origcolor = y .color
x = y .right
if y .p == z then x.p = y
else
RBTransplant(y , y .right)
y .right = z.right
y .right.p = y
RBTransplant(z, y )
y .left = z.left
y .left.p = y ; y .color = z.color
16 RBTransplant(u , v )
if u .p == T .nil then root = v
else
if u == u .p .left then
u .p .left = v
else u .p .right = v
if v 6= nil then v .p = u .p
RBDelete(Node z)
y = z; origcolor = y .color
if z.left == T .nil then
x = z.right
RBTransplant(z, z.right)
else
if z.right == T .nil then
x = z.left
RBTransplant(z, z.left)
else
y = Successor(z)
origcolor = y .color
x = y .right
if y .p == z then x.p = y
else
RBTransplant(y , y .right)
y .right = z.right
y .right.p = y
y zeigt auf den Knoten, der
entweder gelöscht oder
verschoben wird.
16 -
x zeigt auf den Knoten, der die
Stelle von y einnimmt –
das ist entweder das einzige Kind
von y oder T .nil .
RBTransplant(z, y )
y .left = z.left
y .left.p = y ; y .color = z.color
if origcolor == black then RBDeleteFixup(x)
RBDelete(Node z)
y = z; origcolor = y .color
if z.left == T .nil then
x = z.right
RBTransplant(z, z.right)
else
if z.right == T .nil then
x = z.left
RBTransplant(z, z.left)
else
y = Successor(z)
origcolor = y .color
x = y .right
if y .p == z then x.p = y
else
RBTransplant(y , y .right)
y .right = z.right
y .right.p = y
RBTransplant(z, y )
y .left = z.left
y .left.p = y ; y .color = z.color
y zeigt auf den Knoten, der
entweder gelöscht oder
verschoben wird.
16 -
x zeigt auf den Knoten, der die
Stelle von y einnimmt –
das ist entweder das einzige Kind
von y oder T .nil .
Falls y ursprünglich rot war,
bleiben alle R-S-Eig. erhalten:
• Keine Schwarzhöhe hat sich
verändert.
• Keine zwei roten Knoten
sind Nachbarn geworden.
• y rot ⇒ y 6= Wurzel ⇒
Wurzel bleibt schwarz.
if origcolor == black then RBDeleteFixup(x)
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
Repariere“ Knoten x zählt eine schwarze Einheit extra
”
(E5):
(ist also rot-schwarz“ oder doppelt schwarz“)
”
”
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
Repariere“ Knoten x zählt eine schwarze Einheit extra
”
(E5):
(ist also rot-schwarz“ oder doppelt schwarz“)
”
”
Ziel: Schiebe die überzählige schwarze Einheit nach oben, bis:
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
Repariere“ Knoten x zählt eine schwarze Einheit extra
”
(E5):
(ist also rot-schwarz“ oder doppelt schwarz“)
”
”
Ziel: Schiebe die überzählige schwarze Einheit nach oben, bis:
– x ist rot-schwarz ⇒ mach x schwarz.
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
Repariere“ Knoten x zählt eine schwarze Einheit extra
”
(E5):
(ist also rot-schwarz“ oder doppelt schwarz“)
”
”
Ziel: Schiebe die überzählige schwarze Einheit nach oben, bis:
– x ist rot-schwarz ⇒ mach x schwarz.
– x ist Wurzel ⇒ schwarze Extra-Einheit verfällt.
17 -
RBDeleteFixup
Was kann schief gehen, wenn y schwarz war?
(E2) y war Wurzel, und ein rotes Kind von y wurde Wurzel.
(E4) x und x .p sind rot.
(E5) Falls y verschoben wurde, haben jetzt alle Pfade,
die vorher y enthielten, einen schwarzen Knoten zu wenig.
Repariere“ Knoten x zählt eine schwarze Einheit extra
”
(E5):
(ist also rot-schwarz“ oder doppelt schwarz“)
”
”
Ziel: Schiebe die überzählige schwarze Einheit nach oben, bis:
– x ist rot-schwarz ⇒ mach x schwarz.
– x ist Wurzel ⇒ schwarze Extra-Einheit verfällt.
– Problem wird lokal durch Umfärben & Rotieren gelöst.
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
if x == x .p .left then
x
w = x .p .right // Schwester von x
A
if w .color == red then
w .color = black
α β
x .p .color = red
LeftRotate(x .p )
w = x .p .right
if w .left.color == black and
w .right.color == black then
w .color = red
x = x .p
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
B
w
D
C
γ
E
δ ε
ζ
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
if x == x .p .left then
x
w = x .p .right // Schwester von x
A
if w .color == red then
w .color = black
α β
Ziel:
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
zu verletzen.
w = x .p .right
if w .left.color == black and
w .right.color == black then
w .color = red
x = x .p
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
B
w
D
C
γ
E
δ ε
Fall 1
ζ
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
if x == x .p .left then
x
w = x .p .right // Schwester von x
A
if w .color == red then
w .color = black
α β
Ziel:
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
zu verletzen.
w = x .p .right
if w .left.color == black and
w .right.color == black then
w .color = red
x = x .p
B
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
x
α
A
B
w
D
C
γ
ζ
δ ε
Fall 1
D
E
C
β γ
E
w
δ
ε
ζ
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
if x == x .p .left then
x
w = x .p .right // Schwester von x
A
if w .color == red then
w .color = black
α β
Ziel:
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
zu verletzen.
w = x .p .right
if w .left.color == black and
w .right.color == black then
w .color = red
Schw. Einheit
raufschieben.
x = x .p
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
B
Farbe c
w
D
C
γ
E
δ ε
Fall 2
ζ
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
B Farbe c
if x == x .p .left then
x
w
w = x .p .right // Schwester von x
A
D
if w .color == red then
w .color = black
α β
Ziel:
C
E
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
γ
δ ε ζ
zu
verletzen.
w = x .p .right
Fall 2
if w .left.color == black and
w .right.color == black then
x B Farbe c
w .color = red
Schw. Einheit
raufschieben.
x = x .p
A
D
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
α
β
C
γ
E
δ ε
ζ
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
B Farbe c
if x == x .p .left then
x
w
w = x .p .right // Schwester von x
A
D
if w .color == red then
w .color = black
α β
Ziel:
C
E
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
γ
δ ε ζ
zu
verletzen.
w = x .p .right
Fall 2
if w .left.color == black and
w .right.color == black then
x B Farbe c
w .color = red
Schw. Einheit
raufschieben.
x = x .p
A
D
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
α
β
C
γ
Bem.:
E
δ ε
ζ
Anz. der schw. Knoten (inkl. Extra-Einh. bei x ) bleibt auf allen Pfaden gleich!
18 -
RBDeleteFixup(RBNode x)
while x 6= root and x .color == black do
B Farbe c
if x == x .p .left then
x
w
w = x .p .right // Schwester von x
A
D
if w .color == red then
w .color = black
α β
Ziel:
C
E
x .p .color = red
w → schwarz
ohne R-S-Eig.
LeftRotate(x .p )
γ
δ ε ζ
zu
verletzen.
w = x .p .right
Fall 2
if w .left.color == black and
w .right.color == black then
x B Farbe c
w .color = red
Schw. Einheit
raufschieben.
x = x .p
A
D
else // kommt gleich!!
else // wie oben; nur left ↔ right
x .color = black
α
β
C
γ
Bem.:
E
δ ε
ζ
Anz. der schw. Knoten (inkl. Extra-Einh. bei x ) bleibt auf allen Pfaden gleich!
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
B
Farbe c
x
A
α
w
D
β
C
γ
E
δ ε
Fall 3
ζ
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
B
Farbe c
x
A
α
w
D
β
C
γ
E
ζ
δ ε
Fall 3
B
Farbe c
A x
α
β
C w
γ
D
δ
E
ε
ζ
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Farbe c
B
x
A
α
w
D
β
c0
γ
C
E
δ ε
Fall 4
ζ
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Farbe c
B
x
A
w
D
β
α
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
A
α
E
C
β γ
c0
δ
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
Bem.: Anz. der schwarzen Knoten
c0
A
C
(inkl. der Extra-Einheit bei x )
bleibt auf allen Pfaden gleich! α β γ δ
E
ε
ζ
x = root
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
19 -
vorher:
# schwarze Einheiten = c + 2
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
Bem.: Anz. der schwarzen Knoten
c0
A
C
(inkl. der Extra-Einheit bei x )
bleibt auf allen Pfaden gleich! α β γ δ
E
ε
ζ
x = root
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
19 -
vorher:
# schwarze Einheiten = c + 2
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
nachher:
c +2
D
Farbe c
B
Bem.: Anz. der schwarzen Knoten
c0
A
C
(inkl. der Extra-Einheit bei x )
bleibt auf allen Pfaden gleich! α β γ δ
E
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Laufzeit? Fall
Fall
Fall
Fall
1:
2:
3:
4:
Farbe c
B
x
A
w
D
β
α
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
A
α
E
C
β γ
c0
δ
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Laufzeit? Fall
Fall
Fall
Fall
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
1: 1 Rotation + O (1)
c0
A
C
2:
3:
α β γ δ
4:
E
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Laufzeit? Fall
Fall
Fall
Fall
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
1: 1 Rotation + O (1)
c0
C
2: O (h) Umfärbungen A
3:
α β γ δ
4:
E
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Laufzeit? Fall
Fall
Fall
Fall
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
1: 1 Rotation + O (1)
c0
C
2: O (h) Umfärbungen A
3: 1 Rotation + O (1) α β γ δ
4:
E
ε
ζ
x = root
19 -
RBDeleteFixup (Forts.)
else
if w .right.color == black then
w .left.color = black
w .color = red
RightRotate(w )
w = x .p .right
w .color = x .p .color
x .p .color = black
w .right.color = black
LeftRotate(x .p )
x = root
Laufzeit? Fall
Fall
Fall
Fall
1:
2:
3:
4:
Farbe c
B
x
A
α
w
D
β
c0
C
γ
E
ζ
δ ε
Fall 4
D
Farbe c
B
1 Rotation + O (1)
c0
C
O (h) Umfärbungen A
1 Rotation + O (1) α β γ δ
1 Rotation + O (1)
E
ε
ζ
x = root
20 -
Zusammenfassung
Laufzeit RBDelete ∈
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup
|
{z
}
O (h )
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
Also gilt (siehe Lemma): h ∈ O (log n)
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
Also gilt (siehe Lemma): h ∈ O (log n)
⇓
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
Also gilt (siehe Lemma): h ∈ O (log n)
⇓
Laufzeit RBDelete ∈ O (log n)
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
Also gilt (siehe Lemma): h ∈ O (log n)
⇓
Laufzeit RBDelete ∈ O (log n)
Satz.
Rot-Schwarz-Bäume implementieren alle
dynamische-Menge-Operationen in O (log n) Zeit,
wobei n die momentane Anz. der Schlüssel ist.
20 -
Zusammenfassung
Laufzeit RBDelete ∈ O (h) + Laufzeit RBDeleteFixup = O (h)
|
{z
}
O (h )
RBDelete erhält die Rot-Schwarz-Eigenschaften.
Also gilt (siehe Lemma): h ∈ O (log n)
⇓
Laufzeit RBDelete ∈ O (log n)
Satz.
Rot-Schwarz-Bäume implementieren alle
dynamische-Menge-Operationen in O (log n) Zeit,
wobei n die momentane Anz. der Schlüssel ist.
Herunterladen