homedukeAlgorithmen & Datenstrukturen mit Java: Rot-Schwarz-Bäume Prof. Dr. Uwe Schmidt FH Wedel

Rot-Schwarz-Bäume

weiter

weiter

Schnittstelle
und Hilfsklassen wie bei binären Suchbäumen.
weiter
Ziel
Die Laufzeitkomplexität für Einfügen und Suchen immer, auch in den schlechtesten Fällen, in O(log n)
weiter
Strategie
1.
Beim Einfügen und Löschen Ausbalancieren on the fly auf dem Rückweg zur Wurzel
2.
Balance-Kriterium abschwächen
nicht
t.minDepth() + 1 >= t.depth()
auch nicht
t.depth() = ⌈log2 (t.size() + 1)⌉
sondern
c * t.minDepth() >= t.depth()
 
mit c = 2 für Rot-Schwarz-Bäume
 
mit c ≈ 1.44 für AVL-Bäume
weiter
Idee
bei Rot-Schwarz-Bäumen
es gibt rote und schwarze Knoten
leere Knoten zählen immer als schwarz eingefärbt
weiter
Invarianten
0.
es gilt die Invariante für den binären Suchbaum
1.
ein roter Knoten besitzt keine roten Kindknoten
2.
alle Pfade von der Wurzel zu einem leeren Knoten enthalten gleich viele schwarze Knoten
3.
der Wurzelknoten ist immer schwarz eingefärbt
weiter
Folgerungen
der längste Pfad ist maximal 2 mal so lang wie der kürzeste
die maximale Tiefe eines Baumes mit n Elementen ist höchstens 2 * ⌈log2 (n + 1)⌉
die Suchzeit ist immer, auch im schlechtesten Fall, logarithmisch abhängig von der Anzahl der Elemente
weiter
Ausbalancieren
das Ausbalancieren geschieht auf dem Rückweg vom Einfügen/Löschen zur Wurzel
es wird nur an schwarzen Knoten ausbalanciert
eine Operation zum Ausbalancieren an einem Knoten läuft in einer beschränkten Zeit, also in O(1)
die Anzahl der Ausbalancier-Schritte ist beschränkt durch die Länge des Pfades
⇒ auch das Einfügen und Löschen läuft in logarithmischer Zeit
weiter
Klassenstruktur
public abstract
    class RedBlackTree
    implements Map {
 
    ...
 
    private static
        class Empty
        extends RedBlackTree {
        ...
    }
 
    private static final
        class Node
        extends RedBlackTree {
 
        final K            k;
        final V            v;
        final int          c// <= color
        final RedBlackTree l;
        final RedBlackTree r;
        ...
    }
 
    static final int RED            =  0;
    static final int BLACK          =  1;
 
    private static final
        RedBlackTree EMPTY
            = new Empty();
 
    // --------------------
    // special stuff for remove
 
    static final int NEGATIVE_BLACK = -1;
    static final int DOUBLE_BLACK   =  2;
 
    private static final
        class DoubleEmpty
        extends Empty {
        ...
    }
 
    private static final
        RedBlackTree DOUBLE_EMPTY
            = new DoubleEmpty();
 
}
Konstruktor-Funktionen
public static RedBlackTree empty() {
    return
        EMPTY;
}
 
public static RedBlackTree singleton(K kV v) {
    return
        new Node(kvREDEMPTYEMPTY);
}
Implementierung
wird in der Vorlesung entwickelt

Letzte Änderung: 12.12.2017
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel