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.