AVL Bäume AVL Bäume Gliederung Algorithmen und Datenstrukturen I Abstrakte Datentypen V: AVL Bäume 1 D. Rösner AVL Bäume Einleitung Rotationen Implementierung Einfachrotationen Doppelrotationen Einfügen Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg c Winter 2009/10, 4. Januar 2010, 2009/10 D.Rösner D. Rösner AuD I 2009/10 . . . AVL Bäume 1 Einleitung Rotationen Implementierung D. Rösner AuD I 2009/10 . . . AVL Bäume Binäre Bäume: AVL Bäume 2 Einleitung Rotationen Implementierung Binäre Bäume: AVL-Bäume AVL-Bäume sind binäre Suchbäume mit einer Balanziertheitsbedingung: in jedem Knoten gilt: die Differenz zwischen der Höhe des linken Teilbaums und der Höhe des rechten Teilbaums ist nie grösser als 1 die Abkürzung AVL geht zurück auf die beiden russischen Mathematiker Adelson-Velskii und Landis, die 1962 diese Datenstruktur definiert haben Diese Bedingung garantiert, dass Suchoperationen auf AVL-Bäumen immer O(log n) Schritte brauchen. Liegt ein AVL-Baum vor, dann muss nur sichergestellt werden, dass Einfügungen oder Löschungen so erfolgen, dass die Balanziertheitsbedingung nicht verletzt bzw. wiederhergestellt wird. vgl. [RL99], Ch. 5.9 D. Rösner AuD I 2009/10 . . . 4 D. Rösner AuD I 2009/10 . . . 5 Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL-Bäume Binäre Bäume: AVL-Bäume 5 4 2 1 7 3 Einleitung Rotationen Implementierung AVL Bäume 2 6 6 8 3 5 8 4 9 Abbildung: Ein AVL-Baum (vgl. [RL99], Fig. 5.6 (a)) D. Rösner AuD I 2009/10 . . . Abbildung: Ein AVL-Baum (vgl. [RL99], Fig. 5.6 (b)) 6 Einleitung Rotationen Implementierung AVL Bäume D. Rösner AuD I 2009/10 . . . AVL Bäume Binäre Bäume: AVL-Bäume 7 Einleitung Rotationen Implementierung Binäre Bäume: Rotationen 6 3 2 Rotationen dienen dazu, die AVL-Eigenschaft wiederherzustellen, wenn diese nach Hinzufügen oder Löschen von Elementen verloren gegangen ist wir betrachten zunächst die beiden einfachen Rotationen: 7 eine Linksrotation geht von einem linken Teilbaum aus und verringert dessen Tiefe spiegelbildlich dazu geht eine Rechtsrotation von einem rechten Teilbaum aus und verringert dessen Tiefe 4 1 vgl. [RL99], Ch. 5.9 Abbildung: Binärer Baum ohne AVL-Eigenschaft (vgl. [RL99], Fig. 5.6 (c)) D. Rösner AuD I 2009/10 . . . 8 D. Rösner AuD I 2009/10 . . . 10 Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL-Bäume Binäre Bäume: AVL-Bäume v lv lv rt lflf lflf v lfrt ... ... ... ... Abbildung: Baum vor Linksrotation (vgl. [RL99], Fig. 5.7 (a)) D. Rösner AuD I 2009/10 . . . rt ... ... ... ... Abbildung: Baum nach Linksrotation (vgl. [RL99], Fig. 5.7 (a)) 11 D. Rösner AuD I 2009/10 . . . Einleitung Rotationen Implementierung 12 Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL-Bäume Binäre Bäume: AVL-Bäume v lf lfrt ... ... ... ... AVL Bäume Einleitung Rotationen Implementierung AVL Bäume rv rv v rtlf rtrt lf rtrt rtlf ... ... ... ... ... ... ... ... ... ... Abbildung: Baum vor Rechtsrotation (vgl. [RL99], Fig. 5.7 (b)) D. Rösner AuD I 2009/10 . . . ... ... Abbildung: Baum nach Rechtsrotation (vgl. [RL99], Fig. 5.7 (b)) 13 D. Rösner AuD I 2009/10 . . . 14 AVL Bäume Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL-Bäume Einleitung Rotationen Implementierung Binäre Bäume: AVL Bäume 6 3 2 Frage: in welchen Fällen erlauben Links- bzw. Rechtsrotationen, nach Einfügung eines zusätzlichen Elements in einen AVL-Baum die AVL-Eigenschaft wiederherzustellen? Antwort: 7 4 3 .............................................. .............................................. .............................................. 1 Abbildung: Binärer Baum ohne AVL-Eigenschaft (vgl. [RL99], Fig. 5.8) 2 1 6 4 vgl. [RL99], Ch. 5.9.2 7 Abbildung: AVL-Eigenschaft durch Linksrotation wiederhergestellt (vgl. [RL99], Fig. 5.8) D. Rösner AuD I 2009/10 . . . AVL Bäume 15 Einleitung Rotationen Implementierung D. Rösner AuD I 2009/10 . . . AVL Bäume Binäre Bäume: AVL Bäume 16 Einleitung Rotationen Implementierung Binäre Bäume: AVL Bäume aber: die einfachen Links- bzw. Rechtsrotationen reichen leider nicht aus, um die AVL-Eigenschaft nach beliebigen Einfügungen wiederherzustellen für die Fälle, in denen die einfachen Links- bzw. Rechtsrotationen nicht ausreichen, werden zusätzlich zwei sogenannte Doppelrotationen benötigt: Frage: Was ist ein minimales Beispiel dafür? Links-Rechts-Rotation Rechts-Links-Rotation .............................................. .............................................. .............................................. vgl. [RL99], Ch. 5.9.2 Frage: Verallgemeinerung? vgl. [RL99], Ch. 5.9.2 D. Rösner AuD I 2009/10 . . . 17 D. Rösner AuD I 2009/10 . . . 18 AVL Bäume Einleitung Rotationen Implementierung Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL Bäume Binäre Bäume: AVL-Bäume v die Doppelrotationen lassen sich jeweils als Hintereinanderausführung zweier einfacher Rotationen darstellen lv eine Links-Rechts-Rotation besteht aus einer Rechts-Rotation gefolgt von einer Links-Rotation analog: eine Rechts-Links-Rotation besteht aus einer Links-Rotation gefolgt von einer Rechts-Rotation rt lflf im folgenden wird die Links-Rechts-Rotation schematisch erläutert lfrv ... ... als Übung empfohlen: schematische Darstellung einer Rechts-Links-Rotation vgl. [RL99], Ch. 5.9.2 ... ... lfrtlf lfrtrt ... ... ... ... Abbildung: Baum vor Links-Rechts-Rotation (vgl. [RL99], Fig. 5.10 (a)) D. Rösner AuD I 2009/10 . . . AVL Bäume 19 D. Rösner AuD I 2009/10 . . . Einleitung Rotationen Implementierung Einleitung Rotationen Implementierung AVL Bäume Binäre Bäume: AVL-Bäume 20 Binäre Bäume: AVL-Bäume v lfrv lfrv rt lv lv lflf ... ... lfrtrt lfrtlf v ... ... lflf lfrtlf lfrtrt rt ... ... ... ... ... ... ... ... ... ... Abbildung: Baum nach Links-Rechts-Rotation (vgl. [RL99], Fig. 5.10 (a)) ... ... Abbildung: Baum nach Zwischenschritt Rechts-Rotation D. Rösner AuD I 2009/10 . . . 21 D. Rösner AuD I 2009/10 . . . 22 Einleitung Rotationen Implementierung AVL Bäume AVL Bäume AVL Bäume Einleitung Rotationen Implementierung AVL Bäume Rotationen werden durch Pattern matching wie folgt implementiert ([RL99], Ch. 5.9.1): Linksrotation Implementierung in Haskell Moduldefinition ([RL99], Ch. 5.9): module AVLTree(AVLTree,emptyAVL,addAVL) where rotateLeft,rotateRight :: (Ord a,Show a) => AVLTree a -> AVLTree a data (Ord a,Show a) => AVLTree a = EmptyAVL | NodeAVL a (AVLTree a) (AVLTree a) deriving Show emptyAVL = EmptyAVL D. Rösner AuD I 2009/10 . . . AVL Bäume rotateLeft EmptyAVL rotateLeft (NodeAVL v (NodeAVL lv lflf lfrt) rt) = NodeAVL lv lflf (NodeAVL v lfrt rt) 24 D. Rösner AuD I 2009/10 . . . Einleitung Rotationen Implementierung AVL Bäume AVL Bäume = EmptyAVL 25 Einleitung Rotationen Implementierung AVL Bäume analog wird bei den Doppelrotationen vorgegangen ([RL99], Ch. 5.9.2) Links-Rechts-Rotation ... Rechtsrotation dRotateLeftRight , dRotateRightLeft :: (Ord a,Show a) => AVLTree a -> AVLTree a rotateRight EmptyAVL = EmptyAVL dRotateLeftRight (NodeAVL v (NodeAVL lv lflf (NodeAVL lfrv lfrtlf lfrtrt)) rt) = NodeAVL lfrv (NodeAVL lv lflf lfrtlf) (NodeAVL v lfrtrt rt) rotateRight (NodeAVL v lf (NodeAVL rv rtlf rtrt)) = NodeAVL rv (NodeAVL v lf rtlf) rtrt D. Rösner AuD I 2009/10 . . . 26 D. Rösner AuD I 2009/10 . . . 27 AVL Bäume Einleitung Rotationen Implementierung AVL Bäume AVL Bäume Einleitung Rotationen Implementierung AVL Bäume: Einfügen ein Element mit Wert i wird zunächst – wie bei binären Suchbäumen üblich – entsprechend seinem Verhältnis zum Wurzelelement rekursiv in den linken bzw. rechten Teilbaum eingefügt bleibt dabei die AVL-Eigenschaft erhalten, ist nichts weiter zu tun, andernfalls ... Rechts-Links-Rotation dRotateRightLeft (NodeAVL v lf (NodeAVL rv (NodeAVL rtlv rtlflf rtlfrt) rtrt)) = NodeAVL rtlv (NodeAVL v lf rtlflf) (NodeAVL rv rtlfrt rtrt) erfolgte die Einfügung im linken Teilbaum und unterscheidet sich dessen Höhe nun um 2 von der Höhe des rechten Teilbaums: vergleiche i mit dem Wert an der Wurzel des linken Teilbaums ist i kleiner, dann führe eine einfache Linksrotation aus, andernfalls führe eine Links-Rechts-Rotation aus ... D. Rösner AuD I 2009/10 . . . AVL Bäume 28 Einleitung Rotationen Implementierung D. Rösner AuD I 2009/10 . . . AVL Bäume AVL Bäume: Einfügen 29 Einleitung Rotationen Implementierung AVL Bäume: Einfügen Implementation in Haskell ([RL99], Ch. 5.9.3): Einfügen in einen leeren AVL-Baum analog: erfolgte die Einfügung im rechten Teilbaum und unterscheidet sich dessen Höhe nun um 2 von der Höhe des linken Teilbaums: addAVL i EmptyAVL= NodeAVL i EmptyAVL EmptyAVL Einfügen in einen nichtleeren AVL-Baum vergleiche i mit dem Wert an der Wurzel des rechten Teilbaums ist i grösser, dann führe eine einfache Rechtsrotation aus, andernfalls führe eine Rechts-Links-Rotation aus addAVL i (NodeAVL v lf rt) | i < v = let newlf@(NodeAVL newlfv _ _) = addAVL i lf in if ((height newlf - height rt) == 2) then if i < newlfv then rotateLeft (NodeAVL v newlf rt) else dRotateLeftRight (NodeAVL v newlf rt) else (NodeAVL v newlf rt) | otherwise = ... ... Damit: die AVL-Eigenschaft ist dann wieder hergestellt (Begründung?) ([RL99], Ch. 5.9.3) D. Rösner AuD I 2009/10 . . . 30 D. Rösner AuD I 2009/10 . . . 31 AVL Bäume Einleitung Rotationen Implementierung AVL Bäume AVL Bäume: Einfügen AVL Bäume: Einfügen Variante der Implementation in Haskell: Struktur der Definition von addAVL für nichtleeren AVL-Baum Implementation in Haskell: Definition von addAVL für nichtleeren AVL-Baum ... | otherwise = let newrt@(NodeAVL newrtv _ _) = addAVL i rt in if ((height newrt - height lf) == 2) then if i > newrtv then rotateRight (NodeAVL v lf newrt) else dRotateRightLeft (NodeAVL v lf newrt) else (NodeAVL v lf newrt) D. Rösner AuD I 2009/10 . . . AVL Bäume Einleitung Rotationen Implementierung addAVL i root@(NodeAVL v lf rt) | i < v = ... | i > v | otherwise = root -- i == v, already there where newlf@(NodeAVL newlfv _ _) = addAVL i lf newrt@(NodeAVL newrtv _ _) = addAVL i rt 32 D. Rösner AuD I 2009/10 . . . Einleitung Rotationen Implementierung AVL Bäume AVL Bäume: Einfügen 33 Einleitung Rotationen Implementierung AVL Bäume: Einfügen Variante der Implementation: Definition von addAVL für nichtleeren AVL-Baum cont. Variante der Implementation: Definition von addAVL für nichtleeren AVL-Baum ... | i > v = if ((height newrt - height lf) == 2) then if i > newrtv then rotateRight (NodeAVL v lf newrt) else dRotateRightLeft (NodeAVL v lf newrt) else (NodeAVL v lf newrt) | otherwise = root -- i == v, already there; nothing to add where newlf@(NodeAVL newlfv _ _) = addAVL i lf newrt@(NodeAVL newrtv _ _) = addAVL i rt addAVL i root@(NodeAVL v lf rt) | i < v = if ((height newlf - height rt) == 2) then if i < newlfv then rotateLeft (NodeAVL v newlf rt) else dRotateLeftRight (NodeAVL v newlf rt) else (NodeAVL v newlf rt) | i > v = ... D. Rösner AuD I 2009/10 . . . = ... 34 D. Rösner AuD I 2009/10 . . . 35 AVL Bäume Einleitung Rotationen Implementierung AVL Bäume AVL Bäume: Einfügen AVL Bäume: Einfügen Hilfsfunktion zur Bestimmung der Höhe Definition: height EmptyAVL Hilfsfunktion zur Bestimmung der Höhe mögliche Verbesserung: Information zur Höhe nicht jeweils neu berechnen, sondern in den Knoten speichern (s. Übung) = 0 ebenfalls als Übung: Entwurf und Implementation der Operation delAVL zum Entfernen eines Elements aus einem AVL-Baum height (NodeAVL _ lf rt) = 1 + max (height lf) (height rt) D. Rösner AuD I 2009/10 . . . AVL Bäume Einleitung Rotationen Implementierung 36 Einleitung Rotationen Implementierung Literatur: I Fethi Rabhi and Guy Lapalme. Algorithms – A Functional Programming Approach. Pearson Education Ltd., Essex, 1999. 2nd edition, ISBN 0-201-59604-0. D. Rösner AuD I 2009/10 . . . 38 D. Rösner AuD I 2009/10 . . . 37