1. Binäre Suchbäume Binäre Suchbäume realiesieren Wörterbücher. Sie unterstützen die Operationen 1. Einfügen (Insert) 2. Entfernen (Delete). Suchen (Search) 4. Maximum/Minimum-Suche 5. Vorgänger (Predecessor), Nachfolger (Successor) Laufzeit für alle Operationen proportional zur Höhe des Baums. Später spezielle Suchbäume bei denen Höhe logarithmisch in Anzahl der Knoten ist. 1
Suchbaum-Eigenschaft (1) Binäre Suchbäume sind binäre Bäume. Bestehen aus Objekten mit Feldern für Verweis 1. p auf Eltern 2. right auf rechtes Kind. left auf linkes Kind Zusätzlich Feld key für Schlüssel, dabei sind Schlüssel natürliche Zahlen. 2
Suchbaum-Eigenschaft (2) Es gilt Suchbaum-Eigenschaft: Für jedes Objekt x und jedes Objekt y im linken Teilbaum von x gilt key[y] key[x]. Für jedes Objekt x und jedes Objekt y im rechten Teilbaum von x gilt key[y] key[x].
Binäre Bäume - Illustration root[t] / / / / / / / / / / / / / 4
Illustration von Suchbäumen 5 7 2 5 8 2 7 5 8 5 5
Durchlaufen von Suchbäumen (1) Suchbaum-Eigenschaft erlaubt es, Schlüssel im Baum in sortierter Reihenfolge auszugeben. Dazu wird der Baum in Inorder durchlaufen. D.h. die Wurzel eines Teilbaums wird zwischen den Knoten des linken und des rechten Teilbaums ausgegeben. Alternativen Methoden, die Knoten eines Suchbaums zu durchlaufen, sind: 1. Postorder 2. Preorder 6
Durchlaufen von Suchbäumen (2) ( x) Inorder - Tree - Walk 1 if x NIL 2 then Inorder - Tree - print( x) 4 Inorder - Tree - Walk Walk ( left[ x] ) ( right[ x] ) Satz 1.1: Ist x Wurzel eines Baums mit n Knoten, so benötigt Algorithmus Inorder-Tree-Walk bei Aufruf mit Knoten x Zeit Θ(n). 7
Suchen in Suchbäumen Ziel: Finde in einem Suchbaum Knoten x mit Schlüssel k. Falls kein Knoten mit Schlüssel im Suchbaum enthalten, Ausgabe NIL. ( x,k ) Tree - Search 1 if x = NIL k = key[ x] 2 return x if k < key[ x] 4 then Tree - Search 5 else Tree - Search( ) ( left[ x],k ) right[ x],k Aufruf bei Suche in Baum T mit Tree-Search(root[T],k). Lemma 1.2: Tree-Search hat Laufzeit Θ(h), wobei h die Höhe des Baums T ist. 8
Suchen in Suchbäumen (2) 15 6 18 7 17 20 2 4 1 9 Suche nach Schlüssel 9: 9
Iteratives Suchen in Suchbäumen Iterative - Tree - 1 while x NIL k 2 do if k < key then x 4 else x 5 return x Search ( x,k ) key[ x] [ x] left[ x] right[ x] 10
Finden von Minimum/Maximum Ziel: Finde in einem Suchbaum Knoten x mit minimalem bzw. maximalem Schlüssel. ( x) Tree - Minimum 1 while left[ x] NIL 2 do x left return x [ x] ( x) [ x] Tree - Maximum 1 while right 2 do x return x NIL right [ x] Aufruf bei Baum T mit Tree-Minimum(root[T]) bzw. Tree-Maximum(root[T]). Lemma 1.: Tree-Minimum und Tree-Maximum haben Laufzeit Θ(h), wobei h die Höhe des Baums T ist. 11
Finden des direkten Nachfolgers(1) Ziel: Gegeben Suchbaum T und Knoten x mit Schlüssel k, finde Objekt mit nächst größerem Schlüssel (unter Annahme, dass alle Schlüssel unterschiedlich). Lemma 1.4: Besitzt x ein rechtes Kind, so ist der direkte Nachfolger von x der Knoten mit minimalem Schlüssel im rechtem Teilbaum von x. Besitzt x kein rechtes Kind, so ist der direkte Nachfolger von x der niedrigste Vorfahr von x, dessen linkes Kind ebenfalls ein Vorfahr von x ist (dabei ist ein Knoten Vorfahr von sich selbst). 12
Finden des direkten Nachfolgers (2) 15 6 18 7 17 20 2 4 1 9 Nachfolger von Schlüssel 1: 1
Finden des direkten Nachfolgers() Tree - 1 if 2 y 4 5 6 7 ( x) Successor right[ x] NIL then return Tree - Minimum p[ x] while y NIL x = right[ y] do x y y p[ y] return y ( right[ x] ) Lemma 1.5: Tree-Search hat Laufzeit Θ(h), wobei h die Höhe des Baums T ist. 14
Einfügen eines Elements (1) Idee: Finde Knoten mit höchstens einem Kind, für den einzufügender Knoten Wurzel des fehlenden Teilbaums werden kann. 6 11 2 4 9 1 8 10 Einfügen von Schlüssel 8 : 15
Einfügen eines Elements (2) ( T,z) Tree - Insert 1 y NIL 2 x root[ T ] while x NIL 4 do y x 5 if key 6 then 7 else 8 p[ z] y 9 if y = NIL 10 then root 11 else if key 12 then 1 else [ z] < key[ x] x left[ x] x right[ x] [ T ] z [ z ] < key [ y ] left[ y] z right [ y ] z > Baum T war leer 16
Einfügen eines Elements () Lemma 1.6: Tree-Insert hat Laufzeit Θ(h), wobei h die Höhe des Baums T ist. 17
Entfernen von Elementen (1) Betrachten beim Entfernen von Knoten drei Fälle: 1. Zu entfernender Knoten ist Blatt. 2. Zu entfernender Knoten besitzt nur ein Kind.. Zu entfernender Knoten besitzt zwei Kinder. Behandlung der drei Fälle: 1. Blatt kann einfach entfernt werden. 2. Knoten wird durch sein einziges Kind ersetzt.. Nutzen aus, dass direkter Nachfolger kein linkes Kind besitzt. Ersetzen Knoten durch direkten Nachfolger und entfernen Nachfolger wie in 2. aus seiner ursprünglichen Position. 18
Entfernen eines Blattes 6 6 2 11 2 11 4 9 1 4 9 1 5 z 19
Entfernen eines Elements mit 1 Kind 6 6 z 2 4 11 9 1 4 5 11 9 1 5 20
Entfernen eines Elements mit 2 Kindern z 6 z 6 y 9 2 11 2 11 4 y 9 1 4 10 1 5 10 5 9 2 11 4 10 1 5 21
Entfernen von Elementen (2) ( T,z) [ z] = NIL right[ z] Tree - Delete 1 if left = NIL 2 then y z else y Tree - Successor( z) 4 if left[ y] NIL 5 then x left[ y] 6 else x right[ y] 7 if x NIL 8 then p[ x] p[ y] 9 if p[ y] = NIL 10 then root[ T ] x 11 else if y = left[ p[ y ] 12 then y ] x 1 else right[ p[ y ] x 14 if y z 15 then key[ z] key[ y] 16 Satellitendaten von y werden nach z kopiert 22
Laufzeit von Einfügen und Entfernen Lemma 1.7: Tree-Delete hat Laufzeit Θ(h), wobei h die Höhe des Baums T ist. 2