1 Algorithmen und Datenstrukturen Wintersemester 2015/16 13. Vorlesung Binäre Suchbä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 W örterbuch Anfragen Implementierung: je nachdem... 3 Implementierung Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) Θ (n ) Θ (1) Θ (1) sortiertes Feld Min/Max Pred/Succ Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) 3 Implementierung Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) Θ (n ) Θ (1) Θ (1) sortiertes Feld Min/Max Pred/Succ Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) 3 Implementierung Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld Min/Max Pred/Succ 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld Min/Max Pred/Succ 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld Min/Max Pred/Succ 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld w h(T ) = Höhe des Baums T Min/Max Pred/Succ 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld w Min/Max Pred/Succ h(T ) = Höhe des Baums T = Anz. Kanten auf längstem Wurzel-Blatt-Pfad 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld w ` T` Min/Max Pred/Succ h(T ) = Höhe des Baums T r = Anz. Kanten auf längstem Wurzel-Blatt-Pfad ( 0Finden Sie die falls Baum = Blatt = Tr 1Rekursionsgleichung! + max{h(T` ), h(Tr )} sonst. 3 Implementierung ?) unter bestimmten Annahmen. Search Ins/Del unsortierte Liste Θ (n) Θ (1) Θ (n ) Θ (n ) unsortiertes Feld Θ (n) Θ (1)/Θ (n) Θ (1) Θ (n ) ? Θ (n ) Θ (1) Θ (1) Hashtabelle Θ (1)? Θ (1)? − − Binärer Suchbaum Θ (h) Θ (h ) Θ (h ) Θ (h ) sortiertes Feld w ` T` Min/Max Pred/Succ h(T ) = Höhe des Baums T r = Anz. Kanten auf längstem Wurzel-Blatt-Pfad ( 0 falls Baum = Blatt = Tr 1 + max{h(T` ), h(Tr )} sonst. 4-1 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 4-2 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 4-3 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 4-4 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 4-5 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 4-6 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-7 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-8 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-9 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-10 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-11 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: hier 13 Suche 21! im Worst Case n Schritte 4-12 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-13 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-14 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bFinden n/2c) + undRekursions(un)gleichung!! T (1) = 1 Sie1 die ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-15 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-16 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-17 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-18 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-19 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-20 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-21 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 | {z } ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-22 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 | {z } blog2 nc ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-23 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 | {z } = 1 + blog2 nc blog2 nc ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-24 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte ? ? Schritte grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 Übung! ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 | {z } = 1 + blog2 nc = dlog2 (n + 1)e blog2 nc ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-25 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte dlog2 (n + 1)e Schritte? grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 Übung! ≤ T (bn/4c) + 1 + 1 ≤ · · · ≤ T (1) + 1 + · · · + 1 | {z } = 1 + blog2 nc = dlog2 (n + 1)e blog2 nc ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-26 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-27 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte dlog2 (n + 1)e Schritte? 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-28 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte dlog2 (n + 1)e Schritte? 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-29 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-30 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! Suche 27! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-31 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! Suche 27! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-32 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! Suche 27! Suche 17! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-33 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! Suche 27! Suche 17! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-34 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche 21! Suche 27! Suche 17! im Worst Case n Schritte dlog2 (n + 1)e Schritte? ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-35 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche Suche Suche Suche im Worst Case n Schritte dlog2 (n + 1)e Schritte? 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-36 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche Suche Suche Suche im Worst Case n Schritte dlog2 (n + 1)e Schritte? 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-37 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Lineare Suche: Binäre Suche: hier 13 4 Suche Suche Suche Suche im Worst Case n Schritte dlog2 (n + 1)e Schritte? 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 20 ? ) Je nach Implementierung braucht ein Schritt ein oder zwei Vergleiche (z.B. = und <). 4-38 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 4-39 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 4-40 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 6 19 4-41 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 6 3 19 9 14 24 4-42 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-43 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Binärer Suchbaum 12 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-44 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Binärer Suchbaum 12 6 19 3 2 9 5 8 14 11 13 24 17 21 27 Kreisfreier Graph 4-45 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Jeder Knoten hat höchstens zwei Kinder. Binärer Suchbaum 12 6 19 3 2 9 5 8 14 11 13 24 17 21 27 Kreisfreier Graph 4-46 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Binärer Suchbaum 12 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-47 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-48 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-49 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-50 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-51 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 4-52 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 Binärer-Suchbaum-Eigenschaft: 21 27 4-53 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 Binärer-Suchbaum-Eigenschaft: 21 27 Für jeden Knoten v gilt: 4-54 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 Binärer-Suchbaum-Eigenschaft: Für jeden Knoten v gilt: alle Knoten im linken Teilbaum von v haben Schlüssel ≤ v .key 4-55 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 12 Binärer Suchbaum 6 19 3 2 9 5 8 14 11 13 24 17 21 27 Binärer-Suchbaum-Eigenschaft: Für jeden Knoten v gilt: alle Knoten im linken Teilbaum von v haben Schlüssel ≤ v .key ≥ rechten 5 Bin. Suchbaum Abs. Datentyp BinSearchTree() Implementierung 5 Bin. Suchbaum root left right Abs. Datentyp BinSearchTree() Implementierung 5 Bin. Suchbaum root key left right Abs. Datentyp BinSearchTree() Implementierung 5 Bin. Suchbaum root p key left right Abs. Datentyp BinSearchTree() Implementierung p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung Node key key Node left Node right Node p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung Node Node root key key Node left Node right Node p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung Node(key k , Node par) Node key = k p = par right = left = nil Node root key key Node left Node right Node p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung root = nil Node(key k , Node par) Node key = k p = par right = left = nil Node root key key Node left Node right Node p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung root = nil Node(key k , Node par) Node key = k p = par right = left = nil Node root Node Search(key k ) Node Insert(key k ) Delete(Node x ) Node Minimum() Node Maximum() Node Predecessor(Nd. x) Node Successor(Node x) key key Node left Node right Node p 5 Bin. Suchbaum root p key p left right Abs. Datentyp BinSearchTree() Implementierung root = nil Node(key k , Node par) Node key = k p = par right = left = nil Node root Node Search(key k ) Node Insert(key k ) Delete(Node x ) Node Minimum() Node Maximum() Node Predecessor(Nd. x) Node Successor(Node x) o T key key Node left Node right Node p ! o d 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 2. Gib den Schlüssel der Wurzel aus. 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 2. Gib den Schlüssel der Wurzel aus. 3. Durchlaufe rekursiv rechten Teilbaum der Wurzel. 6 Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 2. Gib den Schlüssel der Wurzel aus. 3. Durchlaufe rekursiv rechten Teilbaum der Wurzel. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 6 Inorder-Traversierung root p key p left right (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 2. Gib den Schlüssel der Wurzel aus. 3. Durchlaufe rekursiv rechten Teilbaum der Wurzel. Code: InorderTreeWalk(Node x = root) if x 6= nil then Geben Sie eine rekursive InorderTreeWalk( x .left) Implementierung gib x .key aus an! InorderTreeWalk(x .right) 6 Inorder-Traversierung root p key p left right (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 1. Durchlaufe rekursiv linken Teilbaum der Wurzel. 2. Gib den Schlüssel der Wurzel aus. 3. Durchlaufe rekursiv rechten Teilbaum der Wurzel. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: Code: Baum leer, d.h. root = nil InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: Code: Baum leer, d.h. root = nil X InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: Baum leer, d.h. root = nil X InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. Tlinks und Trechts haben Höhe < h. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. [rekursive Def. der Höhe!] Tlinks und Trechts haben Höhe < h. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: Code: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. [rekursive Def. der Höhe!] Tlinks und Trechts haben Höhe < h. Also werden ihre Schlüssel sortiert ausgegeben. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. [rekursive Def. der Höhe!] Tlinks und Trechts haben Höhe < h. Also werden ihre Schlüssel sortiert ausgegeben. Binärer-Suchbaum-Eigenschaft ⇒ Ausgabe (sortierte Schlüssel von Tlinks , dann root.key, dann sortierte Schlüssel von Trechts ) ist sortiert. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 7 Korrektheit zu zeigen: Schlüssel werden in sortierter Rf. ausgegeben. Induktion über die Baumhöhe h. h = −1: h ≥ 0: X Baum leer, d.h. root = nil Ind.-Hyp. sei wahr für Bäume der Höhe < h. Seien Tlinks und Trechts li. & re. Teilbaum der Wurzel. [rekursive Def. der Höhe!] Tlinks und Trechts haben Höhe < h. Also werden ihre Schlüssel sortiert ausgegeben. Binärer-Suchbaum-Eigenschaft ⇒ Ausgabe (sortierte Schlüssel von Tlinks , dann root.key, dann sortierte Schlüssel von Trechts ) ist sortiert. Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) X 8-1 Laufzeit T (n ) = Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-2 Laufzeit Anz. der Knoten im linken / rechten Teilbaum der Wurzel ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 Code: falls n = 1, sonst. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-3 Laufzeit Anz. der Knoten im linken / rechten Teilbaum der Wurzel ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 Code: falls n = 1, sonst. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-4 Laufzeit Anz. der Knoten im linken / rechten Teilbaum der Wurzel ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-5 Laufzeit Anz. der Knoten im linken / rechten Teilbaum der Wurzel ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-6 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-7 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Code: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-8 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. Für Bäume gilt: #Kanten = #Knoten − 1 = n − 1 Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-9 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. Für Bäume gilt: #Kanten = #Knoten − 1 = n − 1 Übung: zeig’s mit Induktion! Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-10 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. Für Bäume gilt: #Kanten = #Knoten − 1 = n − 1 Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-11 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. Für Bäume gilt: #Kanten = #Knoten − 1 = n − 1 ⇒ T (n) = c1 · (n − 1) + c2 · n ∈ O (n). Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 8-12 Laufzeit ( 1 T (n ) = T (k ) + T (n − k − 1) + 1 falls n = 1, sonst. Zeige (mit Substitutionsmethode) T (n) ≤ c · n − 1 oder: Für jeden Knoten und jede Kante des Baums führt InorderTreeWalk eine konstante Anz. von Schritten aus. Für Bäume gilt: #Kanten = #Knoten − 1 = n − 1 ⇒ T (n) = c1 · (n − 1) + c2 · n ∈ O (n). Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) Laufzeit: 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) h Laufzeit: 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) h Laufzeit: O (h) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv Code: if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) h Laufzeit: O (h) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) h Laufzeit: O (h) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) while x 6= nil and x .key 6= k do if k < x .key then x = x .left else x = x .right return x h Laufzeit: O (h) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) while x 6= nil and x .key 6= k do if k < x .key then x = x .left else x = x .right return x h Laufzeit: O (h) 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) h Laufzeit: O (h) while x 6= nil and x .key 6= k do Laufzeit: if k < x .key then x = x .left else x = x .right return x 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) h Laufzeit: O (h) while x 6= nil and x .key 6= k do Laufzeit: O (h) if k < x .key then x = x .left else x = x .right return x 9 Suche Aufgabe: Schreiben Sie Pseudocode für die rekursive Methode Node Search(key k , Node x = root) rekursiv iterativ if x == nil or x .key == k then return x if k < x .key then return Search(k , x .left) else return Search(k , x .right) h Laufzeit: O (h) while x 6= nil and x .key 6= k do Laufzeit: O (h) if k < x .key then Trotzdem schneller, x = x .left da keine Verwaltung der rekursiven else x = x .right Methodenaufrufe. return x 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 12 6 3 19 9 14 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 12 6 3 19 9 14 Antwort: Min steht ganz links, Max ganz rechts! 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 12 6 3 19 9 14 Antwort: Min steht ganz links, Max ganz rechts! Aufgabe: Schreiben Sie für binäre Suchbäume die Methode Node Minimum(Node x = root) — iterativ! 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 12 6 3 19 9 14 Antwort: Min steht ganz links, Max ganz rechts! Aufgabe: Schreiben Sie für binäre Suchbäume die Methode Node Minimum(Node x = root) — iterativ! if x == nil then return nil while x .left 6= nil do x = x .left return x 10 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 12 6 3 19 9 14 Antwort: Min steht ganz links, Max ganz rechts! Aufgabe: Schreiben Sie für binäre Suchbäume die Methode Node Minimum(Node x = root) — iterativ! if x == nil then return nil while x .left 6= nil do x = x .left return x 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. 11-2 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. 12 6 19 9 8 14 13 17 11-3 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = 12 6 19 9 8 14 13 17 11-4 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. 12 6 19 9 8 14 13 17 11-5 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 6 19 9 8 14 13 17 11-6 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 6 19 9 8 14 13 17 11-7 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 Nachfolger(19) := nil 6 19 9 8 14 13 17 11-8 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 Nachfolger(19) := nil 6 19 9 8 14 13 17 Nachfolger(12) = ? 11-9 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 Nachfolger(19) := nil 6 19 9 8 Nachfolger(12) = ? 14 13 17 13 == Minimum( 12.right“) ” 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 Nachfolger(19) := nil 6 19 9 8 14 13 Nachfolger(12) = ? Nachfolger(9) = ? 17 13 == Minimum( 12.right“) ” 9 hat kein rechtes Kind; 9 == Maximum( 12.left“) ” 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 6 19 9 8 14 13 17 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 6 Node Successor(Node x ) 19 x 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 y 6 Node Successor(Node x ) 19 x 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. 12 y x Node Successor(Node x ) 6 19 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. y 12 x Node Successor(Node x ) 6 19 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. y 12 x Node Successor(Node x ) 6 19 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. y 12 x Node Successor(Node x ) 6 19 9 8 14 13 17 if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 11-1 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = Knoten mit kleinstem Schlüssel unter allen y mit y .key > x .key. = arg miny {y .key | y .key > x .key}. y 12 x Node Successor(Node x ) 6 19 9 8 14 13 17 Tipp: Probieren Sie auch z.B. Successor(“19”)! if x .right 6= nil then return Minimum(x .right) y = x .p while y 6= nil and x == y .right do x =y y = y .p return y 12-1 Einfügen Node Insert(key k ) 12 6 19 3 9 5 8 14 13 Insert(11) 17 12-2 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 8 14 13 Insert(11) 17 12-3 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right x 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 8 14 13 Insert(11) 17 12-4 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right x 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 8 14 13 Insert(11) 17 12-5 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right x 12 6 19 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z y 8 14 13 Insert(11) 17 12-6 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right x 12 6 19 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z y 8 14 13 Insert(11) 17 12-7 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right y 12 x 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 8 14 13 Insert(11) 17 12-8 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right x 6 19 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 12 y 8 14 13 Insert(11) 17 12-9 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 6 x 3 19 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 12 y 8 14 13 Insert(11) 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 x 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 13 Insert(11) 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 13 Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 13 Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 14 8 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 12-1 Einfügen Node Insert(key k ) y = nil x = root while x 6= nil do y =x if k < x .key then x = x .left else x = x .right 12 6 3 9 5 z = new Node(k , y ) if y == nil then root = z else if k < y .key then y .left = z else y .right = z return z 19 y 8 14 11 13 z Insert(11) x == nil 17 13-1 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 12 1. z hat keine Kinder. 6 19 14 2. z hat ein Kind x . 3. z hat zwei Kinder. 13 17 13-2 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 12 1. z hat keine Kinder. 6 19 14 2. z hat ein Kind x . 3. z hat zwei Kinder. z 13 17 13-3 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 12 1. z hat keine Kinder. 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 19 14 2. z hat ein Kind x . 3. z hat zwei Kinder. z 13 17 13-4 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 12 1. z hat keine Kinder. 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 19 14 2. z hat ein Kind x . 3. z hat zwei Kinder. nil z 13 17 13-5 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 1. z hat keine Kinder. 12 z 19 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 14 2. z hat ein Kind x . 3. z hat zwei Kinder. 13 17 13-6 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 1. z hat keine Kinder. 12 z 19 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 14 2. z hat ein Kind x . Setze den Zeiger von z .p , der auf z zeigt, auf x . Setze x .p = z .p . Lösche z . 3. z hat zwei Kinder. 13 17 13-7 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: 1. z hat keine Kinder. 12 z 19 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 14 2. z hat ein Kind x . Setze den Zeiger von z .p , der auf z zeigt, auf x . Setze x .p = z .p . Lösche z . 3. z hat zwei Kinder. 13 17 13-8 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: z 12 1. z hat keine Kinder. 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 19 14 2. z hat ein Kind x . Setze den Zeiger von z .p , der auf z zeigt, auf x . Setze x .p = z .p . Lösche z . 3. z hat zwei Kinder. 13 17 13-9 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: z 12 1. z hat keine Kinder. 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 19 14 2. z hat ein Kind x . y Setze den Zeiger von z .p , der auf z zeigt, auf x . Setze x .p = z .p . Lösche z . 13 17 3. z hat zwei Kinder. Setze y = Successor(z ) und z .key = y .key. Lösche y . (Fall 1 oder 2!) 13-1 Löschen Sei z der zu löschende Knoten. Wir betrachten drei Fälle: z 13 12 1. z hat keine Kinder. 6 Falls z linkes Kind von z .p ist, setze z .p .left = nil ; sonst umgekehrt. Lösche z . 19 14 nil y 13 Setze den Zeiger von z .p , der auf z zeigt, auf x . Setze x .p = z .p . Lösche z . 2. z hat ein Kind x . 17 3. z hat zwei Kinder. Setze y = Successor(z ) und z .key = y .key. Lösche y . (Fall 1 oder 2!) 14 Zusammenfassung Satz. Binäre Suchbäume implementieren alle dynamische-Menge-Operationen in O (h) Zeit, wobei h die momentane Höhe des Baums ist. 14 Zusammenfassung Satz. Aber: Binäre Suchbäume implementieren alle dynamische-Menge-Operationen in O (h) Zeit, wobei h die momentane Höhe des Baums ist. 14 Zusammenfassung 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). 14 Zusammenfassung 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: 14 Zusammenfassung 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 14 Zusammenfassung 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)