Vorlesung Datenstrukturen AVL-Baum Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 407 Globales vs. lokales Balancieren Globales Balancieren Die Balancierung eines Baumes mit Hilfe des DSW-Algorithmus‘ involviert in der Regel jeden Knoten durch Rotationsoperationen. Obwohl das Ergebnis der globalen Balancierung ein perfekt balancierter Baum ist, macht es aus Performanzgründen keinen Sinn, einen Suchbaum nach jeder Einfüge- oder Löschoperation global zu balancieren. Lokales Balancieren Baumbalancierung kann auch lokal auf dem durch eine Einfüge- oder Löschoperation betroffenen Teilbaum durchgeführt werden. Voraussetzung dafür ist die Lockerung der Balancierkriterien: Statt eines perfekt balancierten Baumes erwarten wir lediglich einen balancierten Baum mit einem maximalen Höhenunterschied von Eins bei den beiden Teilbäumen eines Knotens für jeden Knoten des Baums. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 408 AVL-Bäume (1) Definition AVL-Bäume (nach Adelson-Velskii und Landis) sind balancierte Bäume, d.h. die Höhe der Teilbäume jedes Knotens darf um maximal Eins differieren. Forderung Einfüge- und Löschoperationen auf AVL-Bäumen müssen sicherstellen, dass die definierende Eigenschaft nicht verletzt wird. Eigenschaften von AVL-Bäumen Für jede beliebige Knotenanzahl N ist die Höhe hB eines balancierten Baumes nie mehr als 45% größer als die seines perfekt balancierten Pendants. Es gilt: log(N+1) ≤ hB < 1.44 log(N+2) – 0.328 Konsequenz Die Suche eines Elements in einem AVL-Baum läuft in O(log n). Wie wir später noch sehen werden, gilt diese Zeitkomplexität auch für das Einfügen oder Löschen eines Elements. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 409 AVL-Bäume (2) Best Case Im Idealfall sind auch AVL-Bäume völlig ausgeglichen, da jeder perfekt balancierte Baum natürlich auch balanciert ist. Worst Case Um den AVL-Baum mit der geringsten Knotenanzahl (AVL) zu konstruieren, müssen wir für jeden Knoten den maximalen Höhenunterschied seiner Teilbäume erzwingen: AVLh = AVLh-1 + AVLh-2 + 1 (AVL0 = 0, AVL1 = 1) Korrespondenz Da dieses Prinzip eng mit der Bildung der Fibonaccizahlen verwandt ist, werden die entstehenden Bäume auch Fibonacci-Bäume genannt. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 410 Fibonacci-Bäume Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 411 Realisierung von AVL-Bäumen Nach dem Einfügen oder Löschen eines Knotens müssen wir überprüfen, ob die Balancierungseigenschaft noch gilt. Prinzipiell haben wir zwei Möglichkeiten zur Bestimmung des Balancierungsfaktors: Implizite Balancierungsinformation Hierbei müsste die Balancierungsinformation direkt aus der Baumstruktur durch Ermittlung der Höhen der beiden Teilbäume gewonnen werden. Diese Variante benötigt zwar keinen zusätzlichen Speicher, führt aber zu einem laufzeittechnischen Overhead, der die Bemühungen um logarithmische Laufzeit konterkariert. Explizite Balancierungsinformation Wir erweitern (auf Kosten zusätzlich benötigten Speicherplatzes) die Struktur jedes Baumknotens um eine Balancierungskomponente, die die Höhendifferenz zwischen rechtem und linkem Teilbaum angibt: d = hrechterTeilbaum – hlinkerTeilbaum • d ist positiv rechter Teilbaum ist höher als linker • d ist gleich 0 linker und rechter Teilbaum besitzen die gleiche Höhe • d ist negativ linker Teilbaum ist höher als rechter Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 412 Doppelrotationen Der Grundgedanke hinter AVL-Bäumen ist der Zwang, diese immer balanciert zu halten, d.h. nach Einfügen oder Löschen eines Knotens muss getestet werden, ob einzelne Knoten des Baums das AVL-Kriterium verletzen. Wenn ja, müssen diese Knoten in die jeweilige Gegenrichtung rotiert werden. Allerdings gibt es Situationen, in denen eine einfache Rotation dazu nicht ausreicht: 1) Ist der rechte Teilbaum eines rechtslastigen (Balance > 0) Knotens linkslastig (Balance < 0), kann diese Situation nur durch zwei aufeinander folgende Rotationen beseitigt werden: • Zuerst rotieren wir den linkslastigen Teilbaum nach rechts, womit dieser rechtslastig wird. • Danach können wir mit Hilfe einer Linksrotation den rechtslastigen Knoten mit seinem jetzt rechtslastigen Teilbaum ausbalancieren. 2) Ist der linke Teilbaum eines linkslastigen (Balance < 0) Knotens rechtslastig (Balance > 0), kann diese Situation nur durch zwei aufeinander folgende Rotationen beseitigt werden: • Zuerst rotieren wir den rechtslastigen Teilbaum nach links, womit dieser linkslastig wird. • Danach können wir mit Hilfe einer Rechtsrotation den linkslastigen Knoten mit seinem jetzt linkslastigen Teilbaum ausbalancieren. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 413 Einfügen in einen AVL-Baum (1) Verletzung des AVL-Kriteriums Wird nach dem Einfügen der Balancierungsfaktor eines Knotens kleiner als –1 oder größer als +1, muss ein Baum balanciert werden. Situationen Bei Verletzung unterscheiden wir vier Situationen (zwei + zwei symmetrische): 1. Einfügen in den rechten Teilbaum des rechten Kinds Q von Knoten P ⇒ Linksrotation von P 2. Einfügen in den linken Teilbaum R des rechten Kinds Q von Knoten P ⇒ Doppelrotation nötig: Rechtsrotation von Q, Linksrotation von P 3. Einfügen in den linken Teilbaum des linken Kinds Q von Knoten P ⇒ Rechtsrotation von P 4. Einfügen in den rechten Teilbaum R des linken Kinds Q von Knoten P ⇒ Doppelrotation nötig: Linksrotation von Q, Rechtsrotation von P Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 414 Einfügen in einen AVL-Baum (2) Bestandsaufnahme Wir wissen, wie die Verletzung des Balancierungskriteriums rückgängig zu machen ist. Wir wissen nicht, wie wir den Knoten P finden (1) und ob weitere Teilbäume über P neu balanciert werden müssen (2). Maßnahmen 1) Wir bewegen uns von der Einfügeposition aufwärts zur Wurzel und aktualisieren dabei den Balancierungsfaktor des besuchten Knotens (dies kann auf dem Rückweg der Rekursion des Findens der Einfügeposition geschehen). Den ersten Knoten, der nach der Aktualisierung das AVL-Kriterium verletzt, verwenden wir als Knoten P und balancieren diesen Teilbaum gemäß den in der Vorfolie vorgestellten Strategien. 2) Die Balancierfaktoren der P übergeordneten Knoten verändern sich nach der Balancierung nicht, müssen also nicht aktualisiert werden. Demzufolge ist der komplette Baum nach der Behandlung von P wieder balanciert. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 415 Löschen im AVL-Baum (1) Ablauf Zunächst entfernen wir den zu löschenden Knoten mittels Löschen durch Kopieren. (Durch Anwendung dieses Verfahrens stellen wir sicher, nur auf der Blattebene zu löschen und damit die Höhe der betroffenen Teilbäume höchstens um Eins zu reduzieren.) Danach aktualisieren wir die Balanceinformationen beginnend mit dem Vater des gelöschten Knotens bis zur Wurzel. Verletzt dabei ein Balancefaktor das AVL-Kriterium, müssen wir den betreffenden Teilbaum neu balancieren. (Im Gegensatz zum Einfügen wird die Aktualisierung der Balanceinformationen in jedem Fall bis zur Wurzel fortgeführt.) Konsequenz Das Löschen eines Knotens kann zu O(log n) Rotationen führen. Achtung Das Löschen eines Knotens muss nicht sofort eine Verletzung des Balancekriteriums bewirken, sondern kann zunächst sogar zu einer lokalen Verbesserung der Teilbaumdifferenzen führen (von +1 bzw. –1 zu 0). Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 416 Löschen im AVL-Baum (2) Bei Verletzung des AVL-Kriteriums Wir unterscheiden vier Fälle (zwei und ihre symmetrischen Pendants) 1. Wir löschen einen Knoten aus dem linken Teilbaum von P, dessen Höhe sich dadurch um 1 verringert, womit P anschließend das AVL-Kriterium verletzt (+2). Der rechte Teilbaum von P sei Q. a) Der Balancefaktor von Q ist +1 oder 0: Wir rotieren P nach links b) Der Balancefaktor von Q ist –1. R sei der linke Teilbaum von Q: Wir rotieren Q nach rechts und anschließend P nach links 2. Wir löschen einen Knoten aus dem rechten Teilbaum von P, dessen Höhe sich dadurch um 1 verringert, womit P anschließend das AVL-Kriterium verletzt (–2). Der linke Teilbaum von P sei Q. a) Der Balancefaktor von Q ist -1 oder 0: Wir rotieren P nach rechts b) Der Balancefaktor von Q ist +1. R sei der rechte Teilbaum von Q. Wir rotieren Q nach links und anschließend P nach rechts Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 417 Zusammenfassung Wie ist die Balance im AVL-Baum nach einer Verletzung wieder herzustellen? In welchen Situationen sind Einfachrotationen und wann Doppelrotationen und in welche Richtungen anzuwenden? Nachfolgend sind alle vier Szenarien der Verletzung der AVL-Balance und die zur Behebung nötigen Rotationen nochmals zusammengefasst, unabhängig davon, ob der unbalancierte Teilbaum P aus einer Einfüge- oder Löschoperation resultiert. Ist P rechtslastig ➔ Q ist rechter Teilbaum von P Ist Q linkslastig ➔ R ist linker Teilbaum von Q Ist P linkslastig ➔ Q ist linker Teilbaum von P Ist Q rechtslastig ➔ R ist rechter Teilbaum von Q Rechtsrotation von Q Linksrotation von Q Linksrotation von P Rechtsrotation von P sonst sonst Linksrotation von P Dr. Frank Seifert Rechtsrotation von P Vorlesung Datenstrukturen - Sommersemester 2016 Folie 418 Performanzanalyse Worst-Case-Analyse Aufgrund der schon bekannten Fibonacci-Gestalt eines AVL-Baumes benötigt die Suche nach einem Element bzw. der Einfügeposition oder einem zu löschenden Knoten höchstens 1.44 log(N+2) Schritte. Beim Einfügen kann noch eine Einfach- oder Doppelrotation hinzukommen. Beim Löschen können 1.44 log(N+2) Rotationen hinzukommen. Durchschnittsanalyse / Statistische Untersuchungen (Karlton, 1976) Die Suche benötigt im Schnitt log(N) + 0.25 Schritte. Nur 22% aller Löschoperationen und 47% aller Einfügeoperationen bewirken eine Neubalancierung! Weitere Lockerung des Balancekriteriums (Foster, 1973) Erweiterungen des AVL-Konzepts erlauben Höhenunterschiede von zwei oder sogar drei Ebenen. Verglichen mit normalen AVL-Bäumen resultiert diese Erweiterung in einer allgemeinen Erhöhung dieser Bäume um lediglich 50% im worst case, bewirkt aber eine Verminderung der Restrukturierungskosten um den Faktor 10. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 419 Anwendung von Balanciertechniken Muss man immer balancieren? Versuche haben gezeigt, dass bei einer zufälligen Verteilung der in einen Suchbaum einzufügenden Werte, dieser im Schnitt nur 39% größer wird als sein völlig ausgeglichenes Pendant. Konsequenz für praktische Anwendungen Wenn eine Zufallsverteilung einzufügender Werte bekannt ist, sollte man den zusätzlichen Zeit- und Platzbedarf sowie den Aufwand der Implementierung ständig balancierter Bäume genau mit dem zu erzielenden Nutzen abwägen. So spielt es wahrscheinlich für viele Anwendungen, z.B. einen Suchbaum mit einer Milliarde Elementen wahrscheinlich kaum eine Rolle, ob man maximal 30 oder 42 Vergleichsoperationen benötigt, um ein beliebiges Element im Baum zu finden bzw. ein neues einzufügen. Unter Umständen bietet sich auch eine nur gelegentlich stattfindende Neubalancierung (Reorganisation) des Suchbaums als Alternative zur Verwendung ständig balancierter Bäume an. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 420 Ende der Vorlesung Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 421