Was bisher geschah rekursive Datenstrukturen: I I lineare Datenstrukturen: Liste, Stack, Queue hierarchische Datenstrukturen: Bäume I I I allgemeine Bäume Binäre Bäume Unäre Bäume = Listen Höhe eines Knotens in t: Abstand (Kantenzahl) zur Wurzel Höhe hoehe(t) des Baumes t: maximale Knotenhöhe in t Größe size(t) des Baumes t: Anzahl aller Knoten in t I Binäre Suchbäume: Binäre Bäume mit aufsteigend sortierter Inorder-Folge aller Schlüssel (Schlüsselwerte aus einer total geordneten Menge) Laufzeit für Suche, Einfügen, Löschen: O(hoehe(t)) 122 Balancierte binäre Suchbäume Laufzeit für Suche, Einfügen, Löschen in Baum t mit n Knoten: O(hoehe(t)) Ziel: Laufzeit für Suche, Einfügen, Löschen O(log(n)) Idee: balancierte Suchbäume, in denen die Höhe jedes Blattes (etwa) gleich ist 123 Vollständig balancierte Bäume Binärer Suchbaum t heißt vollständig balanciert, wenn in jedem Knoten Node(x, l, r ) in t gilt: |size(l) − size(r )| ≤ 1 Tiefe jedes Knotens ≤ blog(n)c + 1 Beispiel (Tafel) 124 Operationen in vollständig balancierten Bäumen I Suche O(log(n)) I Einfügen und Löschen: zunächst Einfüge- und Löschoperation für binäre Suchbäume danach muss vollständige Balance wieder hergestellt werden (Rebalacieren) i.A. aufwendig 125 AVL-Bäume (Adelson-Velskii, Landis, 1962) Binärer Suchbaum t heißt AVL-Baum, wenn in jedem Knoten Node(x, l, r ) in t gilt: |hoehe(l) − hoehe(r )| ≤ 1 (AVL-Eigenschaft) Optimierung: Speichern der Balance hoehe(l) − hoehe(r ) in jedem Knoten erlaubt schnellen Test I Suche O(log(n)) I Einfügen und Löschen: zunächst Einfügeoperationen für binäre Suchbäume danach Wiederherstellung der AVL-Eigenschaft 126 Rebalacieren in AVL-Bäumen nach Einfügen (als neues Blatt) oder Löschen (Ersetzen durch einziges Kind oder Minimum im rechten Teilbaum) Verletzung der AVL-Eigenschaft im Knoten (x, l, r ) mit |hoehe(l) − hoehe(r )| = 2 evtl. Verletzung in mehreren Vorgängern des eingefügten Knotens Fälle: I I hoehe(l) = hoehe(r ) nach Einfügen keine Verletzung der AVL-Eigenschaft hoehe(l) = hoehe(r ) + 1 I I I nach Einfügen in l keine Verletzung der AVL-Eigenschaft nach Einfügen in r evtl. Verletzung der AVL-Eigenschaft hoehe(l) + 1 = hoehe(r ) I I nach Einfügen in r keine Verletzung der AVL-Eigenschaft nach Einfügen in l evtl. Verletzung der AVL-Eigenschaft 127 (Einfache) Rotation in AVL-Bäumen bei Verletzungen der AVL-Eigenschaft im tiefsten Knoten k der Form k = Node(x, Node(y , l, r ), s) mit hoehe(l) − 1 = hoehe(r ) = hoehe(s) (Markierung von x: −2, Markierung von y: −) Ersetzung durch lrotate(k ) = Node(y , l, Node(x, r , s)) (Linksrotation) analog: Verletzungen der AVL-Eigenschaft im tiefsten Knoten k der Form k = Node(x, l, Node(y , r , s)) mit hoehe(l) = hoehe(r ) = hoehe(s) − 1 (Markierung von x: +2, Markierung von y: +) Ersetzung durch rrotate(k ) = Node(y , Node(x, l, r ), s) (Rechtsrotation) 128 Doppel-Rotation in AVL-Bäumen bei Verletzungen der AVL-Eigenschaft im tiefsten Knoten der Form Node(x, Node(y , l, Node(z, r , s)), t) mit (Markierungen x: −2, y: +) Ersetzung durch lrrotate(k ) = Node(z, Node(y , l, r ), Node(x, s, t)) Links-Rechts-Rotation: zwei aufeinanderfolgende Rotationen: (y , z), danach (x, z) symmetrischer Fall: Node(x, t, Node(y , Node(z, l, r ), s)) mit (Markierungen x: +2, y: −) Ersetzung durch rlrotate(k ) = Node(z, Node(x, t, l), Node(y , r , s)) Rechts-Links-Rotation: (y , z), danach (x, z) 129 Laufzeit der Operationen in AVL-Bäumen Rebalancieren (Rotationen): O(1) Tiefe von AVL-Bäumen mit n Knoten: O(log(n)) I Suche: O(log(n)) I Einfügen: O(log(n)) I Löschen: O(log(n)) 130