Gliederung 5. Compiler 1. 2. 3. 4. Struktur eines Compilers Syntaxanalyse durch rekursiven Abstieg Ausnahmebehandlung Arrays und Strings 6. Sortieren und Suchen 1. Grundlegende Datenstrukturen 2. Bäume 3. Streuspeicherung 7. Graphen 1. Darstellung und Topologisches Sortieren 2. Kürzeste Wege 3. Fluß- und Zuordnungsprobleme Eigenschaften von binären Bäumen • Ein Binärbaum der Tiefe T hat höchstens 2T -1 Knoten Nmax = 2T-1 Nmax : Maximale Knotenzahl • Die Tiefe eines Binärbaumes mit N Knoten liegt zwischen lg2(N + 1) und N lg2(N+1) ≤ T ≤ N 2 Ausgeglichene Bäume (1) • Suchen in binären Suchbäumen hat die Komplexität O(t), wobei t = Tiefe des Baumes 6 – Beispiel vollständiger Binärbaum: • Anzahl Knoten = 7 • Tiefe des Baumes = 3 • Die Suche benötigt maximal 3 Schritte – Beispiel entarteter Binärbaum: • Tiefe des Baumes = 7 • Suchen benötigt max. 7 Schritte Ob ein Binärbaum entartet oder nicht, hängt von der Reihenfolge ab in der die Elemente eingefügt werden. 9 3 1 10 5 7 1 3 5 6 7 9 10 3 Ausgeglichene Bäume (2) • Die Tiefe eines Binärbaumes ist minimal, wenn er vollständig ist, d.h. jede Ebene (bis auf die Ebene der Blätter) maximal gefüllt ist. • In vollständigen k-nären Bäumen gilt: T = log k ( N + 1) T= Tiefe N= Anzahl der Knoten • Der Wunsch, die Tiefe von Bäumen minimal zu halten führt zum Begriff der ausgeglichenen Bäume: Ein k-närer Baum B ist genau dann ausgeglichen (bzw. balanciert), wenn für seine Tiefe folgendes gilt: T = log k ( N + 1) • Die Ausgeglichenheit wird dadurch erreicht, dass Einfüge- und Löschoperationen diese Eigenschaft sicherstellen. • Beispiele: AVL-Bäume, R/B- und B-Bäume 4 Aufwand beim Ausgleichen 11 1 11 17 5 17 5 2 7 13 13 7 2 Ausgleichen 1 7 • Beim Augleichen muss nahezu jeder Knoten bewegt werden • Hoher Aufwand! 13 2 1 5 11 17 5 AVL-Bäume • AVL-Bäume (Adelson-Velskii und Landis, 1962) sind eine Form von binären Suchbäumen, die das Entarten vermeiden • AVL-Bäume basieren auf einem abgeschwächten Kriterium für eine ausgeglichene Tiefe • AVL-Kriterium: Ein Binärer Suchbaum ist ein AVL-Baum, wenn für jeden (inneren) Knoten der absolute Betrag der Differenz der Tiefen des rechten und linken Teilbaums maximal 1 beträgt • Merke: Es genügt nicht, diese Eigenschaft nur für die Wurzel zu fordern, da beide Teilbäume entartet sein können 6 AVL-Bäume: Beispiel 5 6 7 2 4 1 3 AVL-Baum 6 7 2 4 1 3 5 Kein AVL-Baum 7 Eigenschaften von AVL-Bäumen Für AVL-Bäume mit n Knoten und Tiefe t gilt: • log (n+1) ≤ t < 1, 441 . log (n + 2) AVL-Bäume sind höchstens um circa 44% tiefer als minimal möglich. Die Operationen Suchen, Einfügen und Löschen sind mit einem Aufwand von O(log n) realisierbar. • F(t + 3) - 1 ≤ n ≤ 2t+1 -1, Dabei ist F(k) die k-te Fibonacci-Zahl, definiert durch F(0) = 0, F(1) = 1 und F(k + 2) = F(k + 1) + F(k). 8 Einfügen und Löschen in AVL-Bäumen • AVL-Bäume sind binäre Suchbäume: Alle Suchoperationen (z.B. Suche nach min. bzw. max. Element) können problemlos übernommen werden • Durch Einfüge- und Löschoperationen kann die AVLEigenschaft verloren gehen. Mit Hilfe von Baumtransformationen (Rotation und Doppelrotation) kann die AVL-Eigenschaft wieder hergestellt werden 9 Einfügen in AVL-Bäumen (1) • Balance eines Knotens: Die Differenz der Tiefen der Teilbäumen left und right eines Knotens k wird balance b(k) genannt b(k) = t (left) - t (right) • Für die AVL-Eigenschaft gilt: b(k) є {−1,0,+1} • Nach dem Einfügen eines Knotens kann die Balance auch die Werte –2 und +2 annehmen: b(k) є {−2,−1,0,+1,+2} 10 AVL-Bäume: Balance eines Knotens 17 +1 8 4 19 -1 -1 21 0 10 0 0 9 0 14 0 11 Einfügen in AVL-Bäumen (2) Fälle die zu einer Verletzung der AVL-Eigenschaft führen können: 1. Einfügen im linken Teilbaum des linken Kindes 2. Einfügen im rechten Teilbaum des linken Kindes 3. Einfügen im rechten Teilbaum des rechten Kindes 4. Einfügen im linken Teilbaum des rechten Kindes • Merke: Die Fälle (1) und (3) bzw. (2) und (4) sind symmetrisch und können analog Weise behandelt werden 12 • • Rotation Ausgehend vom neu eingefügten Knoten wird (auf dem Pfad zur Wurzel) der erste unbalancierte Knoten gesucht (In diesem Fall K3). Der Teilbaum mit K3 als Wurzel verletzt die AVL-Eigenschaft. Diese wird durch einfache Rotation von vom Knoten K2 über K3 (so dass der neue Teilbaum die Wurzel K2 hat) wieder hergestellt Single RR-Rotation Single LL-Rotation +1 K3 +2 K3 -2 K2 K2 0 K 1 K1 0 0 0 K1 -1 K2 0 K3 0 0 K3 K2 K1 013 Doppelrotation • • • Ausgehend vom neu eingefügten Knoten wird (auf dem Pfad zur Wurzel) der erste unbalancierte Knoten gesucht (In diesem Fall K3). Der Knoten K1 muss Wurzel des neuen ausgeglichenen Teilbaumes werden, da sein Schlüssel zwischen K2 und K3 liegt. Die Bezeichnung Doppelrotation lässt sich durch das Rotieren von K1 über K2 und K3 Double LR-Rotation -1 K3 K3 -2 Double RL-Rotation K2 K2 K1 0 +2 +1 0 0 K1 K1 0 K1 0 0 K2 K3 0 0 K3 K2 14 Baumtransformation: Vorgehensweise 1. Einfügen in linken Teilbaum des linken Kindes => Rechtsrotation des Vaters 2. Einfügen in rechten Teilbaum des linken Kindes => Doppelrotation (LR) des linken Kindes/Vaters 3. Einfügen in rechten Teilbaum des rechten Kindes => Linksrotation des Vaters 4. Einfügen in linken Teilbaum des rechten Kindes => Doppelrotation rechts/links (RL) des rechten Kindes/Vaters 15 Rotationen im AVL-Baum (1) 16 Rotationen im AVL-Baum (2) 17 Rotationen im AVL-Baum (3) 18 Rotationen im AVL-Baum (4) 19 Löschen in AVL-Bäumen • Löschen funktioniert analog zum Einfügen • Nach dem Löschen eines Schlüssels kann die AVLEigenschaft eines inneren Knotens k verletzt sein – Ggf. Balance des betroffenen, vom Vater aufgespannten Teilbaums durch Rotieren wieder herstellen. – Vorsicht: Rotieren kann Ausgeglichenheit weiterer Knoten auf dem Pfad zur Wurzel verletzen. • Balance rekursiv/iterativ ggf. bis zur Wurzel wieder herstellen. 4 4 2 1 2 5 3 1 4 RR 5 löschen 1 2 +2 3 3 20 2-3-4-Knoten • Ein binärer Suchbaum enthält Knoten mit einem Schlüssel (und den dazu gehörigen Daten) sowie zwei Verweise auf einen linken und rechten Teilbaum, die natürlich auch leer sein können. Solche Knoten werden 2-Knoten genannt • 3-Knoten sind Knoten, die zwei Schlüssel und drei Verweise auf weiterführende Teilbäume enthalten • 4-Knoten sind Knoten, die drei Schlüssel und vier Verweise auf weiterführende Teilbäume enthalten • n-Knoten sind Knoten, die (n-1) Schlüssel und n Verweise auf weiterführende Teilbäume enthalten • 2-Baum: Ein binärer Suchbaum wird 2-Baum genannt, wenn er nur 2-Knoten enthält und alle Blätter auf einer Ebene sind 21 2-3-4-Bäume • 2-3-Bäume: Ein Suchbaum, dessen Knoten alle 2-Knoten oder 3-Knoten sind und dessen Blätter alle auf einer Ebene liegen, wird 2-3-Baum genannt. • 2-3-4-Bäume: Ein Suchbaum, dessen Knoten alle 2Knoten, 3-Knoten oder 4-Knoten sind und dessen Blätter alle auf einer Ebene liegen, werden 2-3-4-Baum genannt. 2-3-4-Baumes der Tiefe 2 22 B-Bäume • B-Bäume (1972 von Bayer und McCreight eingeführt ) stellen eine Verallgemeinerung der 2-3- und der 2-3-4-Bäume dar • Ziel der B-Bäume ist primär den Zugriff auf große Datenbestände (z.B. bei Datenbanken), die überwiegend auf externen Datenträgern (z.B. auf Festplatten, CD-ROM) gespeichert sind und nicht in den Hauptspeicher geladen werden können zu optimieren • Die Anzahl der Plattenzugriffe erweist sich als proportional zur Höhe des B-Baums. Da Plattenzugriffe um Größenordnungen langsamer sind als Hauptspeicherzugriffe, wird versucht, die Höhe niedrig zu halten • B-Bäume werden typischerweise im Zusammenhang mit Datenbanken z.B. für Indexstrukturen verwendet . 23 B-Bäume: Anmerkungen • Bei B-Bäumen variiert der Verzweigungsgrad, während die Tiefe vollständig ausgeglichen ist • B–Bäume sind Bäume mit variabler Kinderzahl (auch Vielwegbäume genannt) • Alle Pfade von der Wurzel bis zu den Blättern sind in einem B-Baum gleich lang • Typischerweise werden B-Bäume hoher Ordnung verwendet – Knoten enthalten sehr viele Werte – Höhe des Baumes ist dafür niedrig. 24 B-Bäume: Grundbegriffe (1) Ein B-Baum der Ordnung n ist ein Suchbaum, für den gilt • Jede Seite (Baumknoten) enthält eine variable Zahl m von Schlüsseln. • Für die Wurzelseite gilt 1 ≤ m ≤ 2n • Für alle Seiten außer der Wurzelseite gilt n ≤ m ≤ 2n • Jede Seite ist entweder eine Blattseite (ohne Nachfolger), oder sie hat m + 1 Nachfolger • Alle Blattseiten liegen auf gleicher Stufe (Tiefe) 25 B-Bäume: Grundbegriffe (2) Für jede Seite (jeder Knoten) eines B-Baumes gilt: • Seien s1, s2, ... , sm-1, sm die Schlüssel in der Seite und u1, u2, ... , um-1, um die Unterseiten der Seite. Es muss gelten: s1 < s2< ... < sm-1< sm • Die Schlüssel in der Unterseite uo (und deren Unterseiten) sind alle kleiner als s1. • Die Schlüssel in der Unterseite um (und deren Unterseiten) sind alle größer als sm und die Schlüssel in anderen Unterseiten ui (und deren Unterseiten) liegen jeweils zwischen sm -1 und si. 26 B-Bäume: Struktur einer Seite • Jede Seite enthält i geordnete Elemente (Schlüsselwerte), wobei es ein Wert m existiert, so dass m ≤ i ≤ 2.m • m wird Ordnung des Baumes genannt • Jede Seite enthält Verweise auf die Kindknoten mit den Unterbäumen, wobei für einen inneren Knoten sind jeweils i+1 Verweise vorhanden 27 B–Baum: Beispiel B-Baum der Ordnung 2 • Der Wurzelknoten enthält einen Schlüssel • Alle anderen Knoten enthalten 2 ≤ m ≤ 4 Schlüssel. 28 Tiefe eines B-Baumes • Die Laufzeit und damit die Anzahl der Festplattenzugriffe ist für die meisten B-Baum-Operationen abhängig von der Tiefe des Baumes • Ist n >1 die Anzahl der Werte (Schlüssel) eines B-Baumes der Tiefe t und der Ordnung m, so gilt: t ≤ log n +1 m 2 . 29 Suchen in B-Bäumen • Die Suche in B-Bäumen kombiniert – Suche in binären Suchbäumen – Suche in Liste bzw. Folgen • Vorgehen bei der Suche nach Schlüsselwert s Beginnend auf der Wurzelseite wird der Eintrag gesucht, der den gesuchten Antrag überdeckt: D.h. es wird das erste Element e gesucht, das größer oder gleich s ist – Falls e=s wurde das gesuchte Element gefunden, die Suche kann abgebrochen werden – Falls e > w muss der Verweis von e zur nächsten Seite weiterverfolgt werden – Falls kein Element kleiner als w gefunden wurde wird der letzte Verweis der Seite verwendet – Falls eine Blattseite erreicht wird, die den gesuchten Wert w nicht enthält, dann existiert der gesuchte Wert nicht im Baum! 30 Suchen in B-Bäumen: Beispiel Suche nach dem Schlüsselwert 38 in B-Baum der Ordnung 2: • Auf der Wurzelseite 0 wird durch Vergleich mit dem Schlüssel 25 der Verweis auf Seite 2 ermittelt und weiterverfolgt • Auf der Seite 2 wird festgestellt, dass sich der Schlüssel zwischen 31 und 40 befinden muss • Durch Verfolgen des Verweises auf Seite 7 und der Suche in der Folge in Seite 7 wird der gesuchte Schlüssel gefunden 31 Aufwand der Suche in B-Bäumen 1. Die Suche innerhalb eines Knotens erfolgt linear und ist beendet, – wenn ein Wert größer oder gleich dem gesuchten Wert ist – oder alle Werte des Knotens betrachtet worden sind. • In einem B-Baum der Ordnung m hat jede Seite höchsten 2m Elemente – Der Aufwand dieser lokalen Suche in O(m) 2. Wird der Wert in einem inneren Knoten nicht gefunden, so wird analog zum binären Suchbaum der nächste Knoten in Richtung der Blätter weitergesucht. – Die Anzahl der besuchten Knoten ist damit abhängig von der Tiefe des Baumes – Der Aufwand dieser Suche ist Θ(t) = Θ(logm n), n: Anzahl der Elemente im B-Baum, t: Tiefe des B-Baumes, m: Ordnung des BBaumes 3. Der Gesamtaufwand der Suche ist Ο(m logm n) 32 Einfügen in B-Bäume (1) Vorgehensweise beim Einfügen eines Schlüssels w in B-Baum 1. Es wird die Blattseite gesucht, in dem der Schlüssel w gespeichert werden soll. Diese Seite hat entweder • Zwei Elemente v und x mit v≤ w ≤ x • Ein Element x als kleinstes Element der Seite mit w ≤ x ist dabei die am • weitestens links stehende Seite im Baum Ein Element v als größtes Element der Seite mit v ≤ w ist dabei die am weitesten rechts stehende Seite im Baum 2. Das neue Element wird in die Seite eingefügt – Falls das Blatt vor dem Einfügen bereits voll (d.h. enthält bereits 2m Elemente), so verstößt der Baum danach gegen die B-Baum-Definition! – Lösung: Beim Auftreten eines Überlaufs muss der „übervolle“ Knoten aufgteilt werden: • • • Die ersten m Werte verbleiben auf der Originalseite Die letzten m Werte werden auf die neue Seite verschoben Das mittlere Element wandert in den Vaterknoten nach oben 33 Einfügen in B-Bäume (2) Beim Einfügen müssen „übervolle“ Knoten aufgeteilt werden • Der neue Vaterknoten muss nun in den ursprünglichen Vaterknoten integriert werden, wodurch wieder die B-Baum-Eigenschaft verletzt sein kann • Rekursiv in Richtung Wurzel ist demnach solange jeder so entstehende „übervolle“ Knoten aufzuteilen, bis spätestens ein neuer Vater die „neue“ Wurzel des Baumes bildet (B-Bäume wachsen in Richtung Wurzel) • Merke: Das Verfahren durchläuft den Baum ggf. zweimal: Erst wird der Baum in Richtung eines Blattes durchsucht, der Knoten eingefügt und dann in Richtung der Wurzel ausgeglichen. • Lösung: Ein effizienteres Verfahren, das den Baum nur einmal durchläuft, teilt auf dem Suchpfad in Richtung des Zielblattes vorsorglich jeden vollen Knoten auf und fügt zum Schluss den Wert in einen Knoten ein, der sicher nicht voll ist (One-pass-Verfahren) 34 Einfügen in B-Bäume (3) Wert 16 einfügen Für die Speicherung von 16 Wurde Seite 4 Festgelegt. Die Seite 4 enthält bereits 4 Elemente und muss aufgeteilt werden. Beim Aufteilen muss das mittlere Element (hier 16) auf die Vaterseite (hier Seite 1) weitergereicht werden 16 Einfügen 35 Einfügen in B-Bäume (4) 36 Löschen in B-Bäume (1) Vorgehensweise beim Löschen eines Schlüssels w aus einem B-Baum • Es wird die Blattseite gesucht, die den zu löschenden Schlüssel enthält • Der Schlüssel wird aus der Seite entfernt, dabei sind zwei Fälle zu unterscheiden: – Falls w auf einer Blattseite gespeichert ist, kann w gelöscht werden. Verbleiben danach weniger als m Elemente auf der Seite, ist ein Unterlauf zu behandeln – Falls w auf einer inneren Seite gespeichert ist, so wird w gelöscht und durch das nächstkleinere Element von einer Blattseite ersetzt. Danach kann sich wieder ein Unterlauf ergeben, der behandelt werden muss. 37 Löschen in B-Bäume (2) • Beim Löschen können Knoten einen Unterlauf aufweisen und damit die B-Baum-Eigenschaft verletzen • Lösung – Ausgleichen • Voraussetzung: Die Nachbarseite hat n Elemente mit n>m • Die Elemente der beiden Seiten und das eingeschlossene Elemente der Vaterseite müssen neu verteilt werden, so dass auf beiden Seiten n Elemente mit m ≤ n vorhanden sind – Vereinigen von zwei Seiten • Falls die Nachbarseite nur n=m besitzt, werden Unterlaufseite und Nachbarseite zusammengelegt • Das von beiden Seiten ‘‘eingeschlossene‘‘ Element der Vaterseite muss heruntergezogen werden, da durch das Zusammenlegen einer der beiden Verweise überflüssig wurde • Die neue Blattseite hat 2m Elemente 38 Löschen in B-Bäume (3) • Löschen von 22 verursacht einen Unterlauf in Seite 5 • Da die linke Nachbarseite voll besetzt ist, können die Elemente 13, 14, 17, 18, 20 und 24 neu verteilt werden: 22 löschen – 13, 14 und 17 verbleiben auf der linken Seite (Seite 4) – 20 und 24 werden in Seite 5 gespeichert – 18 wird in den Vaterknoten aufgenommen (Seite 1) 39 Löschen in B-Bäume (4) • Löschen von 43: Unterlauf in Seite 8 – Die Seite 7 enthält nur 2 Elemente: Seite 7 und Seite 8 können vereinigt werden – Die Elemente der neuen Seite sind: 32, 38 und 42 – Die übergeordnete Seite (Seite 2) verliert das Element 40, das in die neue Seite aufgenommen wird 40 Einfügen und Löschen: Aufwand 1. Zunächst muss der für Einfügen/Löschen relevante Knoten gesucht und der richtige Index i bestimmt werden – Beim Einfügen wird hierfür ein Blatt gesucht, das Löschen kann potenziell jeden Knoten betreffen – Daher liegt die Laufzeit dieser lokalen Suche entsprechend der Laufzeitanalyse für die Suche in O(m logm n) 2. Beim Löschen und beim Einfügen, werden Ausgleichoperationen vorgenommen, die aber lokal und beschräkt sind: Es kommt höchstens eine Konstante hinzu 3. Der Aufwand der beiden Operationen liegt ebenfalls in O(m logm n) 41