7 Binäre Bäume
Literatur:
Kapitel 13 aus [CLR90].
Balancierte Bäume stammen aus [AVL62].
Inhalt
Binäre Bäume ·Baumoperationen
-
Unterstützung vieler Wörterbuchoperationen
- Baumstrukturen effizient
- Effizienz der Operationen proportional Höhe
des Baumes = O(log n) (falls der Baum
``ausgeglichen'')
- Viele Varianten, abhängig von der Anwendung
-
Rot/Schwarz-Bäume [Bay72]
- B-Bäume
- AVL-Bäume [AVL62]
- Splay-Trees
- (a,b)-Bäume, z.B. (2,3)-Bäume (2-3-Bäume)
- selbst-balancierende Bäume
- ...
Definition 2 [Binärer Suchbaum]
Ein binärer Suchbaum ist ein binärer Baum
(left, right, (evtl. parent)) bei dem
für alle Knoten n gilt:
key(l) £ key(n) £ key(r).
wobei l und r beliebige Knoten aus dem rechten bzw. linken Unterbaum von n sind
-
Die Elemente des Baumes sind `` sortiert''
- Þ Ausgeben der sortierten Elemente = rekursives Durchlaufen
des Baumes (in-order tree walk)4
InOrder-Tree-Walk(t) =
if t != nil
then InOrder-Tree-Walk(left(t));
print (key(t));
InOrder-Tree-Walk(right(t));
-
wichtige Operation auf Suchbäumen
- Komplexität: O(h), wobei h die Höhe
- Minimum/Maximum bestimmen: genauso einfach (der linkeste/rechteste
Knoten im Baum)
Search(t,k) = // t : tree, k : key
if t == nil then raise error("Not found")
else if k == key(t) then return t
else if k < key(t)
then Search( left(t),k)
else Search(right(t),k)
Baumoperationen: Suchen (2)
|
Hier das Ganze nochmals iterativ
Search(t,k) = // t : tree, k : key
while (t != nil) and (k != key(t))
do
if k < key(t)
then t := left(t)
else t := right(t)
od;
if (t == nil)
then raise error("Not Found")
else return t
Baumoperationen: Einfügen
|
-
Einfügen immer an den Blättern
- Komplexität: O(h)
Insert(T,z) = // T : tree, z : node to insert
y := nil; x := root(T); // zwei Hilfsvariablen
while x != nil // finde das passende Blatt
do
y := x; // y zum merken des Vaters
if key(z) < key(x)
then x := left(x)
else x := right(x)
od;
p(z) := y; // => x ist nil, y sein Vorgaenger
if y = nil // Sonderfall: y = Wurzel;
then root(T) := z
else if key(z) < key(y)// f"uge an der passenden Stelle
then left(y) := z // z als neues Blatt ein.
else right(y) := z
Delete(T,z) // T = tree, z = zu loeschender Knoten
if left(z) = nil or right(z) = nil
then y := z // y tritt an die Stelle von x
else y := Successor(z); // wobei: y hat <= 1 Kind!
if left(y) != nil // Bestimmung des Kindes x
then x := left(y) // von y.
else x := right(y);
// Ver"andern der Verzeigerung
if x != nil then p(x) = p(y); // y herausgenommen => x mit
// neuem Vater
if p(y) = nil // Spezialfall: wurzel
then root(t) = x
else if y = left(p(y))
then left(p(y)) := x
else right(p(y)) := x // y ist nun vom
// urspr. Platz entfernt
if y != z then key(z) := key(y);// z durch y ersetzen
return y;
January 23, 2001