Praktische Einführung und Programmierung
Stefan Bosse
Universität Koblenz - FB Informatik
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume ::
Übergang von linearen Listen auf Baumstrukturen; Skip-Listen als "Vermittler"
Vor- und Nachteile
Algorithmen
Anwendungen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Motivation
Die bisher betrachteten Datenstrukturen waren im Wesentlichen eindimensional oder linear: sie weisen mit der Vorgänger-Nachfolger-Relation nur eine Form von Beziehungen zwischen den einzelnen Elementen auf.
In diesem Kapitel wollen wir mit den Bäumen eine Klasse von Datenstrukturen kennen lernen, die eine zweite Dimension einbeziehen und dadurch auch die Darstellung von hierarchischen Strukturen ermöglichen.
Baumstrukturen sind nicht nur in der Informatik von fundamentaler Bedeutung, etwa zur Organisation von Daten, sondern sind auch im Alltag in vielfältiger Form wiederzufinden.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Allgemeines Beispiel
Formales Modell
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Allgemein können wir unter einem Baum eine Menge von Knoten ℕ (Nodes) und Kanten 𝔼 (Edges) verstehen, die besondere Eigenschaften aufweisen:
So besitzt jeder Baum genau einen ausgezeichneten Knoten, der als Wurzel bezeichnet wird.
Weiterhin ist jeder Knoten außer der Wurzel durch genau eine Kante mit seinem Vorgängerknoten verbunden.
Jeder Knoten na kann 0..k Nachfolgerknoten u besitzen die durch Kanten ka,u verbunden sind.
Die Kanten sind (zunächst noch) gerichtet ("von oben nach unten")
Ein Knoten oder der Baum haben eine Ordnung d: Die maximale Anzahl von Kanten pro Knoten.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
https://ac.informatik.uni-freiburg.de/lak_teaching/ss_06/info2/Slides/18_Baeume_Grundlagen_Natuerliche_Suchbaeume.pdf Nicht jede Struktur ist ein Baum (aber ein Graph)
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Ein Knoten ohne Nachfolger kann als Blatt(knoten) bezeichnet werden.
Ein Pfad in einem Baum ist eine Folge von unterschiedlichen Knoten, in der die aufeinander folgenden Knoten durch Kanten miteinander verbunden sind.
Weitere Eigenschaften (Parameter) von Bäumen: Höhe und Niveau.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Es muss im Gegensatz zu lineare Listen Entscheidungsfunktionen f geben, die einen Übergang von Knoten na auf einen Nachfolgerknoten nb berechenn.
Ein Baum ist neben einer Beziehungsrelation (Stammbaum) eine Suchmaschine.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Höhe und Niveau von Bäumen
Bottom-up Berechnungsbaum
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Jeder Baum kann in Teilbäume zerlegt werden. Der atomare Baum besteht aus einem Knoten. Bäume sind rekursive Datenstrukturen. Unterbäume sind auch Bäume.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Suche nach Schlüssel s endet beim Suchbaum in Knoten k mit k.key == s oder in Blatt, dessen Intervall s enthält.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Taxonomie
Zusammenfassung:
Baumstrukturen dienen im Wesentlichen zur hierarchischen Repräsentation und Organisation von Daten. Eine der wichtigsten Einsatzgebiete von Bäumen ist jedoch die Unterstützung einer effizienten Suche. Hierfür werden in den einzelnen Knoten eines Baumes neben den eigentlichen Nutzdaten (bzw. einen Verweis darauf) zusätzlich noch Schlüsselwerte gespeichert, über die die Suche erfolgt.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Abstrakter Datentyp Binärer Baum
Für einen aus den Teilbäumen x und y sowie dem Element b konstruierten Baum bin(x,b,y) liefert left demnach den Teilbaum x, right den Teilbaum y und value das Element b. Die beiden weiteren Funktionen empty und is_empty werden zur Konstruktion eines leeren Baumes bzw. zum Test auf einen leeren Baum benötigt.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Abstrakter Datentyp Binärer Baum
type Tree(T)import Booloperators empty : → Tree bin : Tree × T × Tree → Tree left : Tree → Tree right : Tree → Tree value : Tree → T isempty : Tree → Boolaxioms ∀x,y: Tree, ∀b: T left (bin (x, b, y)) = x right (bin (x, b, y)) = y value (bin (x, b, y)) = b isempty (empty) = true isempty (bin (x, b, y)) = false
ADT Tree(T) mit Operatoren und Axiomen die das Verhalten der Operationen definieren
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Datenstrukturen
typeof root = nodetypeof node = { left : node, right : node, data : data, key : number}
typeof root = nodetypeof node = { leaf = { left : node|leaf, key : number, right : node|leaf, data : data key : number }}
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Es gibt wieder den bisher bekannten Satz an Basisoperationen die auf Bäume angewendet werden:
search(k)
insert(node | ⟨data,k⟩)
remove(node|data|k)
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function search (node,k) { if (node.key==k) return node if (node.left && node.left.key<k) return search(node.left,k) if (node.right && node.right.key<k) return search(node.right,k) throw NOTFOUND}search(root,100)
Suche in einem Bereichsbaum nach dem Schlüüsel k
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function node(data,k) { return { children:[],data:data,key:k,keyRange:[k,k] }}function search (node,k) { if (node.key==k) return node for(i=0;i<length(node.children);i++) { if (node.children[i].keyRange[0]>=k && node.children[i].keyRange[1]<=k) return search(node.children[i],k) } throw NOTFOUND}
Suche in einem Bereichsbaum nach dem Schlüüsel k
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Es gibt verschiedene Strategien zur Traversierung (für Suche, Einfügen, Löschen von Knoten) eines Baums.
Ein Beispielsbaum mit den Knoten A,B,C,D,E,F und G
Hier wird zuerst rekursiv der linke Teilbaum besucht, dann der Knoten selbst und anschließend der rechte Teilbaum. Für den binären Baum aus der Abbildung entspricht das der Reihenfolge:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
D → B → E → A → F → C → G
Ein Beispiel für die Anwendung dieser Strategie ist das Auslesen eines Baumes für einen arithmetischen Ausdruck in Infixschreibweise.
Der Algorithmus für einen Inorder-Durchlauf lässt sich am einfachsten rekursiv formulieren. Der gesamte Baum wird nach der Inorder-Strategie durchlaufen, wenn der Algorithmus mit der Wurzel des Baumes als Parameter aufgerufen wird.
function Inorder (k) { // Eingabe: Knoten k eines binären Baumes mit Verweis auf // linken (k.left) und rechten (k.right) Teilbaum sowie // dem Element k seleber (Daten data und Schlüssel k) Inorder (k.left) /* besuche linken Teilbaum */ Process (k.data,k.key) /* Verarbeite aktuellen Knoten */ Inorder (k.right) /* besuche rechten Teilbaum */}
Inorder-Traversierung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Bei dieser Strategie wird zuerst der Knoten selbst besucht und erst danach erfolgt das Traversieren des linken bzw. rechten Teilbaumes. Für den Beispielbaum liefert das die Reihenfolge:
A → B → D → E → C → F → G
Neben der Ausgabe eines arithmetischen Ausdrucks in Präfixschreibweise ist die Erzeugung einer eingerückten Baumdarstellung für ein Dateisystem ein typisches Anwendungsbeispiel. Hier wird zuerst der Name des Verzeichnisses ausgegeben und darunter eingerückt eine Liste der darin enthaltenen Dateien und Verzeichnisse.
Der Algorithmus für den Preorder-Durchlauf kann wiederum rekursiv formuliert werden
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function Preorder (k) { // Eingabe: Knoten k eines binären Baumes mit Verweis auf // linken (k.left) und rechten (k.right) Teilbaum sowie // dem Element k seleber (Daten data und Schlüssel k) Process (k.data,k.key) /* Verarbeite aktuellen Knoten */ Preorder (k.left) /* besuche linken Teilbaum */ Preorder (k.right) /* besuche rechten Teilbaum */}
Preorder-Traversierung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Beim Postorder-Durchlauf werden erst beide Teilbäume durchlaufen, bevor der Knoten selbst besucht wird. Dies führt in unserem Beispiel zur Reihenfolge
D → E → B → F → G → C → A
Ein Beispiel für die Anwendung dieser Strategie ist die Erstellung einer Stückliste mit Aufsummierung, etwa beim UNIX-Kommando du (disk usage), das den Platzbedarf eines Verzeichnisses und aller Unterverzeichnisse im Dateisystem ermittelt. Hierbei werden zuerst die Größen der Einträge in den Blättern (d.h. der Dateien) bestimmt und für den direkten Vaterknoten (d.h. das enthaltende Verzeichnis) addiert. Der Platzbedarf dieser Verzeichnisse wird wiederum zum Platzbedarf des übergeordneten Verzeichnisses zusammengefasst usw., bis die Gesamtgröße der Wurzel bestimmt werden kann.
Wie bereits bei den anderen beiden Strategien wird der Algorithmus zum Postorder-Durchlauf am einfachsten rekursiv formuliert
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function Postorder (k) { // Eingabe: Knoten k eines binären Baumes mit Verweis auf // linken (k.left) und rechten (k.right) Teilbaum sowie // dem Element k seleber (Daten data und Schlüssel k) Postorder (k.left) /* besuche linken Teilbaum */ Postorder (k.right) /* besuche rechten Teilbaum */ Process (k.data,k.key) /* Verarbeite aktuellen Knoten */}
Postorder-Traversierung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Während bei den ersten drei Strategien der Baum zuerst in der Tiefe durchwandert wird, entspricht der Levelorder-Durchlauf einer Breitensuche, d.h., auf jedem Niveau des Baumes werden erst alle Knoten besucht, bevor auf das nächste Niveau gewechselt wird. Danach ergibt sich die Reihenfolge:
A → B → C → D → E → F → G
Der Algorithmus zum Levelorder-Durchlauf ist im Gegensatz zu den bisher betrachteten Strategien nicht rekursiv. Stattdessen wird eine Warteschlange verwendet, in der die noch zu verarbeitenden Knoten abgelegt werden. Der Baum wird durchlaufen, indem der nächste zu besuchende Knoten aus der Warteschlange entnommen wird. Nach dem Besuch dieses Knotens werden die Kinder am Ende der Warteschlange eingetragen, bevor mit dem nächsten Knoten fortgefahren wird.
Die Levelorder-Strategie wird iterativ implementiert.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function Levelorder (k) { // Eingabe: Knoten k eines binären Baumes q = [] // leere Warteschlange; addTail (q, k) /* Wurzel in die Warteschlange aufnehmen */ while (length(q)!=0) { n = removeHead(q); Process (n.data, n.key) addTail(q, n.left) /* linken Knoten eintragen */ addTail(q, n.right) /* rechten Knoten eintragen */ }}
Levelorder-Traversierung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Wenn der Baum nicht geordnet oder die Knoten nicht mit Schlüssel assoziert sind (generischer Baum) müssen alle Teilbäume und Pfade durchsucht werden.
Das klinkt sinnlos, da das Suchen scheinbar wieder einer lineare Liste entspricht.
Aber bei Parallelisierung der Suche in Teilbäume (Divide-and-Conquer Methode) könnte dennoch eine geringere Suchzeit notwendig sein!
function parSearch(node,k) { if (node.key==k) terminateSearchWith(node) startProcess(parSearch,node.left,k) startProcess(parSearch,node.right,k)}parSearch(root,k)
Parallele Suche. Es werden bis zu N-1-L Prozesse gestartet, bei N Knoten und L Endknoten ohne Nachfolger.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Bäume sind daher selber Organisationsstrukturen für Algorithmen die einen Programmablauf steuern können!
Z.B. auch Suche im Internet (Suchmaschine!)
Verteilung von Berechnungen auf Rechner mittels hierarchischer Teilung
Baumstrukturen stellen verteilte Kommunikationsnetze dar (Verbindung von Rechnern), die Kanten sind Kommunikationskanäle.
In Betriebssystemen (UNIX) können Prozesse weietere Prozesse starten. Die neuen Prozesse werden Kindprozesse des Elternprozesses ⇒ Baumstruktur!
Dateisysteme sind Baumstrukturen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Höhe eines symmetrischen ideal besetzten Binärbaums: H=O(log N).
Die Baum-Struktur hängt von Einfügereihenfolge in anfangs leeren Baum ab
Einfügen eines neues Elements (Schlüssel k=5) in einen bestehenden Baum verändert die Höhe des Baums und dessen Symmetrie
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function insert(node,data,k) { if (node.key==k) throw Error; if (k>node.key) { if (!node.right) node.right=Node(data,k) else insert(node.right,data,k) } else { if (!node.left) node.left=Node(data,k) else insert(node.left,data,k) }}if (!root) root=Node(data,k)else insert(root,data,k)
Einfügen eines neuen Datensatzs in einen Binärbaum
Hier wird die Preorder Traversierung angewendet.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Beispiel des Einfügens eines neuen Knotens mit dem Schlüssel k=4
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Die komplizierteste Operation im binären Suchbaum ist das Löschen. Dies liegt daran, dass beim Entfernen eines inneren Knotens einer der beiden Teilbäume des Knotens »hochgezogen« und gegebenenfalls umgeordnet werden muss.
Grundsätzlich müssen beim Löschen eines Knotens k drei Fälle berücksichtigt werden:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
Für das Ersetzen eines Knotens gibt es wiederum zwei Varianten:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function removeNode(root,k) { // Eingabe: Wurzel vom Suchbaum T, Schlüssel k des zu löschenden Elementes node = searchNode (root, k) if (node = null) throw Error parent = searchParent (root, node) // Arrg, sollte mit Search kombiniert werden /* 1. Fall */ if (!node.left && !node.right) { // node ist Blattknoten if (parent.left===node) // node ist linkes Kind parent.left = null else parent.right = null /* 2. Fall */ } else if (!node.left) { if (parent.left===node) // node ist linkes Kind parent.left = node.right else parent.right = node.right } else if (!node.right) { if (parent.left===node) // node ist linkes Kind parent.left = node.left else parent.right = node.left } else /* 3. Fall */ child = minElement (node.right) replaceNode(node,child) // Ersetze node durch child }
Entfernen eines Knotens mit dem Schlüssel k
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Algorithmen
function minElement(node) { if (!node.left && !node.right) return node; if (node.left) return minElement(node.left) else return node}
Minimales Element eines Teilbaums
asdp Löschen im binären Suchbaum
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Komplexität
.. it depends.
Die (erfolglose) Suchzeit als Anzahl der Knoteniterationen ist bei einem ausgeglichenen und symmetrischen Binärbaum einfach gleich der Höhe, und diese ist O(log N) bei N Knoten.
Der Extremfall eines Baums (nicht ausgegelichen und asymmetrisch) ist die lineare Liste (jeder Baum kann in einer lineare Liste transformiert werden). Dann ist die Suchzeit wieder O(N)
In der Realität hat man etwas dazwischen liegendes
Die noch einzuführenden Operationen zum EInfügen und Entfernen von Knoten benötigen i.A. auch eine Suche. Für diese giltg die gleiche Komplexitäsklasse.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
... oder nur Syntaxbaum
Worum geht es? Um Compiler und Syntaxanalyse von Programmen die in einer bestimmten Programmiersrpache geschrieben wurden.
Ein Compiler ist typischweise aus folgenden Komponenten im Schichtenmodell aufgebaut:
Analysephase:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Typisches Schichten- und Phasenmodell eines Compielrs
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Man kann einen Baum auch als geschachtelte Liste (Array) von Listen verstehen.
Daher kann ein Tokenstrom (TOkenliste) mit bestimmten Regeln wieder in eine Baumstruktur transformiert werden.
Konkerter versa abstrakten Syntaxbaum
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Beispiel: Arithmetische Berechnungen wie (x*n+1)/y
code = "(x*n+1)/y"tokens = lexer(code) tokens := [LPAR,LIT(x),MUL,LIT(n),ADD,NUM(1),RPAR,DIV,LIT(y)]tree = parser(tokens)tree := [DIV,[ADD,[MUL,VAR(x),VAR(n)],[NUM(1)]]],[VAR(y)]]
Der Lexer und Parser im Zusammenspiel
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Beim Abstrakten Syntaxbaum fehlen alle unwesentlichen, grammatikspezifischen Elemente:
Strukturen und Bindungen im Syntaxbaum am Beispiel von Ausdrücken. Token werden hierarchisch geordnet, implizite (Bindungs- und Reihenfolge) Regeln werden explizit.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Der Tokenstrom (oder Liste):
Ziele der Abstraktion:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Beispiel der Ezeugung eines Tokenstroms
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Die Suche ist eher sekundär.
Die Transformationen dieses Baumes ist primär und steht im Vordergrund
Ein Beispiel für eine Transformation ist die Konstantenfaltunf, d.h. die Umstellung von Ausdrücken so dass Konstanten zusammengefasst und zur Kompilierungszeit evaluiert werden können.
x = (a+2)-(b+4) = a+2 + (-b) + (-4) = a-b + 2-4 = a-b - 2
Beispiel der Konstantenfaltung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Das Problem bei der Konstantenfaltung: Die Konstanten können in verschiedenen Teilbäumen verteilt sein. Ein Transformation der Baumstruktur kann die Konstanten dann in einem Knoten zusammenbringen.
Wir werden weitere Transformationen von Bäumen kennen lernen (da vor allem zur Symmetrisierung), wie LR und RL Transformationen.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Beispiele
Konstantefaltung durch Baumtransformation mit Operationsnormalisierung
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
»Gute« und »schlechte« Suchbäume
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Ziel ist die Balanzierung von Bäumen um "optimale" Bäume zu erhalten, also balanziert oder ausgeglichen.
Neben vollständig balanzierten Bäumen gibt es schwächere Varianten wie AVL Bäume:
Für die Höhe h eines AVL-Baums mit n Knoten gilt:
hbal≤h≤havl⸤log2(n)⸥≤h≤1.44⋅log2(n+2)–1.33
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
O. Bittel, HTWG Konstanz Verschiedene AVL Bäume im Vergleich zu einem vollständig balanzierten Baum
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Bei Binärbäumen geht die Balanzierung sehr einfach durch Vertauschen von Knoten, wie das bereits bei der Einfügeoperation zu sehen war.
addp Vollständiges Ausgleichen eines Baumes nach Einfügen eines neuen Knotens: Kein Knoten bleibt an seinem Platz! Eine teure Operation!
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
O. Bittel, HTWG Konstanz Rechts-Rotation
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function rotateRight(p) { q = p.left A = q.left B = q.right C = p.right pp = parentOf(p) q.left = A q.right = q p.left = B p.right = C if (pp.left === p) pp.left = q else pp.right= q}
Rechts-Rotation mit Elternsuche von Rotationsknoten p
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function swap(p,q) { data=p.data; key=p.key; p.data=q.data; p.key=q.key; q.data=data; q.key=key}function rotateRight(p) { q = p.left A = q.left B = q.right C = p.right // tauscht Daten und Key, damit wir keinen Elternknoten benötigen!!! // Die parent-p Relation bleibt erhalten swap(p,q) // p ist nun q, q ist nun p p.left = A p.right = q q.left = B q.right = C}
Rechts-Rotation: Optimiert ohne Elternsuche vom Rotationsknoten p
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Fall B: Baum ist rechtslastig, d.h. Höhenunterschied = +2
Unterfall B1: rechter Teilbaum hat Höhenunterschied 0 oder +1:
O. Bittel, HTWG Konstanz Links-Rotation
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function rotateLeft(p) { q = p.right A = p.left B = q.left C = q.right pp = parentOf(p) p.left = A p.right = B q.left = p q.right = C if (pp.left === p) pp.left = q else pp.right= q}
Links-Rotation mit Elternsuche von Rotationsknoten p
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Die Rechts- (genauso analog die Links-) Rotation verändert den Baum, aber ausgeglichen ist er nicht. Dazu wird eine Kombination aus Links- und Rechts-Rotation verwendet.
Fall B: Baum ist rechtslastig, d.h. Höhenunterschied = +2
Unterfall B2: rechter Teilbaum hat Höhenunterschied -1
Rechts-Links-Rotation
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
function Node(data,k) { return { left:null,right:null,data:data,key:k }}function rotateLeft(p) { pp = parentOf(p) q = p.right r = q.left A = p.left ; B = r.left C = r.right ; D = q.right p.left = A ; p.right = B q.left = C ; q.right = D r.left = p ; r.right = q if (pp.left === p) pp.left = r else pp.right= r}
Rechts-Links-Rotation mit Elternsuche von Rotationsknoten p
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Beispiel 1 zu Einfügen in AVL-Bäumen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Beispiel 2 zu Einfügen in AVL-Bäumen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: Transformation von Bäumen
Ein iterativer und rekursiver Vorgang!
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: B-Bäume
Hierbei steht der Name »B« für balanciert, breit, buschig oder auch Bayer, nicht jedoch für binär.
Den Ausgangspunkt bildet somit auch wieder ein ausgeglichener Suchbaum, bei dem alle Pfade von der Wurzel zu den Blättern gleich lang sind.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: B-Bäume
Wendet man das Kriterium der Ausgeglichenheit auf einen Mehrwegebaum an, so müssten folgende Forderungen für einen vollständig ausgeglichenen Baum erfüllt sein:
Das vollständige Ausgleichen in einem solchen Baum wäre jedoch zu aufwendig. Daher wird das B-Baum-Kriterium eingeführt:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: B-Bäume
Struktur einer Seite im B-Baum
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: B-Bäume
Stefan Bosse - Algorithmen und Datenstrukturen - Modul T Bäume :: B-Bäume
Suchen im B-Baum
Bei den Einfüge- und Löschoperationen muss die Forderung nach mindestens m und maximal 2m Elementen pro Seite eingehalten werden.