Algorithmen und Datenstrukturen Wintersemester 2012/13 15. Vorlesung Binäre Suchbäume Prof. Dr. Alexander Wolff Lehrstuhl für Informatik I 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... 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 ) 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 ) 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 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 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 ?) 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 = Höhe des Baums Min/Max Pred/Succ 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 = Höhe des Baums = Anz. Kanten auf längstem Wurzel-Blatt-Pfad 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` r Tr Min/Max Pred/Succ h = Höhe des Baums = Anz. Kanten auf längstem Wurzel-Blatt-Pfad ( 0Finden Sie die falls Baum = Blatt = 1Rekursionsgleichung! + max{h(T` ), h(Tr )} sonst. 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` r Tr Min/Max Pred/Succ h = Höhe des Baums = Anz. Kanten auf längstem Wurzel-Blatt-Pfad ( 0 falls Baum = Blatt = 1 + max{h(T` ), h(Tr )} sonst. Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche 21! 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 Vergleiche 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 Vergleiche 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 Vergleiche 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 Vergleiche 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 Vergleiche 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 Vergleiche 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 Vergleiche ? 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 Vergleiche ? grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? 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 Vergleiche ? 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 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 Vergleiche ? grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 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 Vergleiche ? grob: Wie oft muss ich n halbieren, bis ich bei 1 bin? genau: T (n) ≤ T (bn/2c) + 1 und T (1) = 1 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 Vergleiche ? 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 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 Vergleiche ? 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 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 Vergleiche ? 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 ≤ · · · ≤ 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 Vergleiche ? 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 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 Vergleiche ? 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 } 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 Vergleiche ? 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 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 Vergleiche ? 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 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 Vergleiche ? 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 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 Vergleiche dlog2 (n + 1)e 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 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 Vergleiche dlog2 (n + 1)e 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 Vergleiche dlog2 (n + 1)e 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 Vergleiche dlog2 (n + 1)e 220 − 1 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 Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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! Suche 27! im Worst Case n Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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! Suche 27! im Worst Case n Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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! Suche 27! Suche 17! im Worst Case n Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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! Suche 27! Suche 17! im Worst Case n Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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! Suche 27! Suche 17! im Worst Case n Vergleiche dlog2 (n + 1)e ≈ 1 Mio. 220 − 1 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 Suche Suche Suche im Worst Case n Vergleiche dlog2 (n + 1)e 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 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 Suche Suche Suche im Worst Case n Vergleiche dlog2 (n + 1)e 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 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 Suche Suche Suche im Worst Case n Vergleiche dlog2 (n + 1)e 21! 27! 17! 13! ≈ 1 Mio. 220 − 1 20 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 Suche im sortierten Feld 2 3 5 6 8 9 11 12 13 14 17 19 21 24 27 12 6 19 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 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 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 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 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 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 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 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 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 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 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 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 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: 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 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 Bin. Suchbaum Abs. Datentyp BinSearchTree() Implementierung Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key left right Implementierung p nil Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key p left right nil Implementierung Node key key Node left Node right Node p Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key p left right nil Implementierung Node Node root key key Node left Node right Node p Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key p left right nil Implementierung Node(key k , Node par) Node key = k p = par right = left = nil Node root key key Node left Node right Node p Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key p left right nil 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 Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key left right root = nil Node(key k , Node par) Node Node root Node Insert(key k ) Delete(Node x ) Node Minimum() Node Maximum() Node Predecessor(Nd. x) Node Successor(Node x) nil Implementierung key = k p = par right = left = nil Node Search(key k ) p key key Node left Node right Node p Bin. Suchbaum root p nil Abs. Datentyp BinSearchTree() key left right root = nil Node(key k , Node par) Node Node root Node Search(key k ) Node Predecessor(Nd. x) Node Successor(Node x) nil Implementierung key = k p = par right = left = nil Node Insert(key k ) Delete(Node x ) Node Minimum() Node Maximum() p o T key key Node left Node right Node p ! o d Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Inorder-Traversierung (Binäre) Bäume haben eine zur Rekursion einladende Struktur... Beispiel: Gib Schlüssel eines binären Suchbaums sortiert aus! Lösung: 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. 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. 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. 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) root Inorder-Traversierung nil key p left right p nil (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) root Inorder-Traversierung nil key p left right p nil (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) Korrektheit Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) Korrektheit zu zeigen: Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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 x.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) 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 x.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 Laufzeit T (n ) = Code: InorderTreeWalk(Node x = root) if x 6= nil then InorderTreeWalk(x .left) gib x .key aus InorderTreeWalk(x .right) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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: 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: 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) 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) 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) 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) 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) 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 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 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 Minimum & Maximum Frage: Was folgt aus der Binäre-Suchbaum-Eigenschaft für die Position von Min und Max im Baum? 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 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! 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! 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 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 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. 12 6 19 9 8 14 13 17 Nachfolger (und Vorgänger) Vereinfachende Annahme: alle Schlüssel sind verschieden. Erinnerung: Nachfolger(x ) = 12 6 19 9 8 14 13 17 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 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 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 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 (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) = ? 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“) ” 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“) ” 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 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 = x .p return y 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 = x .p return y 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 = x .p return y 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 = x .p return y 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 = x .p return y 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 = x .p return y 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 = x .p return y Einfügen Node Insert(key k ) y = nil x = root 6 while x 6= nil do y =x 3 9 if k < x .key then x = x .left 5 8 else x = x .right 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 19 14 13 17 Einfügen Node Insert(key k ) 12 y = nil x = root 6 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen x Node Insert(key k ) 12 y = nil x = root 6 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen x y Node Insert(key k ) 12 y = nil x = root 6 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen y Node Insert(key k ) 12 x y = nil x = root 6 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen Node Insert(key k ) 12 x y y = nil x = root 6 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen Node Insert(key k ) 12 y y = nil x = root 6 x 19 while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen Node Insert(key k ) 12 y = nil x = root 6 x 19 y while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) 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 Einfügen Node Insert(key k ) 12 y = nil x = root 6 19 y while x 6= nil do y =x 3 9 14 if k < x .key then x = x .left 5 8 13 17 else x = x .right Insert(11) z = new Node(k , y ) if y == nil then root = z x == nil else if k < y .key then y .left = z else y .right = z return z Einfügen Node Insert(key k ) 12 y = nil x = root 6 19 y while x 6= nil do y =x 3 9 14 p if k < x .key then x = x .left 5 8 11 13 17 else x = x .right Insert(11) z = new Node(k , y ) if y == nil then root = z x == nil else if k < y .key then y .left = z else y .right = z return z Einfügen Node Insert(key k ) 12 y = nil x = root 6 19 y while x 6= nil do y =x 3 9 14 p if k < x .key then x = x .left 5 8 11 13 17 else x = x .right Insert(11) z = new Node(k , y ) if y == nil then root = z x == nil else if k < y .key then y .left = z else y .right = z return z 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 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 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 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 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 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 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 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 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 3. z hat zwei Kinder. Setze y = Successor(z ) und z .key = y .key. Lösche y . 17 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 . 3. z hat zwei Kinder. Setze y = Successor(z ) und z .key = y .key. Lösche y . 17 Zusammenfassung Satz. Binäre Suchbäume implementieren alle dynamische-Menge-Operationen in O (h) Zeit, wobei h die momentane Höhe des Baums ist. 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. 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). 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: 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 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)