DS Vorlesung - TU Chemnitz

Werbung
Vorlesung Datenstrukturen
Balancieren eines Suchbaums
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 396
Baumgestalt vs. Zeitkomplexität
Vorteile eines ausgeglichenen binären Suchbaums
Suchoperation besitzt Zeitkomplexität O(log N) bei N Knoten
Einfügeoperation besitzt Zeitkomplexität O(log N) bei N Knoten
Potenzielle Problematik
Speziell beim wiederholten Einfügen neuer Knoten aber auch beim Löschen (mit der Methode „Löschen durch Verschmelzen“) hatten wir festgestellt, dass ein
Suchbaum degenerieren kann.
Als Konsequenz sinkt die Effizienz der Such- und Einfügeoperationen merklich.
Abhilfe
Wiederherstellen eines ausgeglichenen Baumes durch Balancieren des Baumes.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 397
Balancierte Bäume
Balancierter Baum
Ein binärer Baum wird als balanciert bezeichnet, wenn die absolute Höhendifferenz der
beiden Teilbäume jedes Knotens maximal Eins beträgt.
Perfekt balancierter Baum
Ein balancierter Baum wird als perfekt balanciert angesehen, wenn sich alle Blätter auf
höchstens zwei benachbarten Ebenen befinden.
Voraussetzung für das Balancieren
Binäre Suchbäume haben die Eigenschaft, dass jeder Knoten eines Baumes die Wurzel des
Baumes repräsentieren kann. Da Bäume rekursiv definiert sind, gilt dies natürlich auch für
alle Teilbäume, also alle Knoten eines Baumes.
Konsequenz
Knoten können unter Beibehaltung des Suchbaumkriteriums im Baum verschoben werden.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 398
Balancieren eines Baums (1)
Eigenschaft von Suchbäumen
Jeder Knoten eines Suchbaumes kann unter Beibehaltung des Suchbaumkriteriums
innerhalb des Baumes verschoben werden.
Rotation
Operation zur Vertauschung des Wurzelknotens eines (Teil-)Baums mit einem seiner
beiden Nachfolger.
Forderung an Rotationsoperation
Die Ordnung zwischen den Schlüsselwerten muss bewahrt werden.
Varianten
Linksrotation
Rechtsrotation
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 399
Rechtsrotation
Bedeutung
node* rotateRight( node* n ) {
if ( n ) {
Ein Knoten wird durch seinen linken Kindknoten
node* temp = n->left;
ersetzt ➔ der Kindknoten rotiert nach rechts.
if ( temp ) {// linkes Kind vorhanden?
Bedingung
n->left = temp->right;
temp->right = n;
Existenz eines nichtleeren linken Teilbaums.
n = temp;
}
Konsistenzbewahrung
}
Der ersetzte Knoten (der größer als sein bisheriger
return n; // neue Teilbaumwurzel
linker Kindknoten ist) wird rechter Nachfolger seines
}
(ehemals) linken Kindknotens (Rotation nach rechts).
Beachte, dass die neue Teilbaumwurzel im
Der rechte Teilbaum des ehemaligen linken
Kindknotens wird linker Nachfolger des ersetzten
Knotens.
Dr. Frank Seifert
Anschluss noch genau an der Stelle in den
übergeordneten Knoten eingehängt werden muss,
an der sich die alte Teilbaumwurzel befand.
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 400
Linksrotation
Bedeutung
node* rotateLeft( node* n ) {
if ( n ) {
Ein Knoten wird durch seinen rechten Kindknoten
node* temp = n->right;
ersetzt ➔ der Kindknoten rotiert nach links.
if ( temp ) { // rechtes Kind vorhanden?
n->right = temp->left;
Bedingung
temp->left = n;
Existenz eines nichtleeren rechten Teilbaums.
n = temp;
}
Suchbaumerhaltung
}
Der ersetzte Knoten (der kleiner als sein bisheriger
rechter Kindknoten ist) wird linker Nachfolger seines
return n; // neue Teilbaumwurzel
}
(ehemals) rechten Kindknotens (Rotation nach links). Beachte, dass die neue Teilbaumwurzel im Anschluss
Der linke Teilbaum des ehemaligen rechten
Kindknotens wird rechter Nachfolger des ersetzten
Knotens.
Dr. Frank Seifert
noch genau an der Stelle in den übergeordneten
Knoten eingehängt werden muss, an der sich die alte
Teilbaumwurzel befand.
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 401
Balancieren eines Baumes (2)
Mit Hilfe von Rotationen transformieren wir den zu balancierenden Baum zunächst in die Form einer linearen
Liste. Diese stellt eine einheitliche Ausgangsform („Rückgrat“) für alle Bäume dar und bildet die Basis für
das anschließende eigentliche Balancieren.
node* createBackbone( node* n ) {
if ( n ) {
while ( n->left )
// Rotiere jeweilige Wurzel nach rechts
n = rotateRight( n );
// bis diese keinen linken Teilbaum mehr besitzt
node* temp = n, *save = n;
temp = temp->right;
while ( temp ) {
if ( temp->left ) {
// wenn temp ein linkes Kind besitzt
temp = rotateRight(temp);// rotiere temp nach rechts und
save->right = temp;
// hänge den rotierten Knoten in den Baum
}
else { save = temp; temp = temp->right; } // Fahre mit rechtem Kind fort
}
}
return n;
// Rückgabe der Wurzel des „Listen“-Baumes
}
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 402
Balancieren eines Baumes (3)
Zweiter Schritt
Wir transformieren den „Listenbaum“ in einen perfekt balancierten Baum.
DSW-Algorithmus (Day, Stout, Warren)
In mehreren Durchläufen wird, jeweils mit der Wurzel beginnend, jeder zweite (rechte) Knoten
linksrotiert:
Im ersten Durchlauf ergibt sich die Anzahl der auszuführenden Linksrotationen aus der Differenz
der vorhandenen Knotenanzahl N des Baumes zur Knotenanzahl M des nächst kleineren
vollständig gefüllten binären Baumes.
M = 2"lg(N +1)# −1
Die Anzahl der auszuführenden Linksrotationen der nächsten Durchläufe ergibt sich danach
direkt aus der Knotenanzahl€des jeweils nächst kleineren vollständig gefüllten binären Baumes.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 403
Balancieren eines Baumes (4)
node* perfectTreePass(node* root, int M) {// M ist Anzahl der Rotationen
node* temp, * prev;
node* save = root->right,
node* next = save->right;
for ( int i = 0; i < M; i++ ) {
// M-Mal wird jeder zweite Knoten des Baumes
if ( i )
// nach links rotiert
prev->right = rotateLeft( temp );
else
root = rotateLeft( root );
// Bei Rotation um Wurzel ergibt sich neue Wurzel
temp = next;
// Zuweisen des übernächsten (vor der Rotation)
prev = save;
// Folgeknotens
if (next) {
// Weiterrücken um zwei Knoten jeweils
save = next->right;
if ( save )
next = save->right;
Achtung:
}
Es werden nicht alle Ausnahmesituationen abgefangen!
}
return root;
}
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 404
Balancieren eines Baumes (5)
Zeitkomplexität
Die Generierung des Backbone benötigt bestenfalls N Schritte (wenn der Baum schon ein
Backbone ist) und schlimmstenfalls 2N–1 Schritte mit N–1 Rotationen ➔ Komplexität O(N).
Der DSW-Algorithmus benötigt im ersten Durchlauf N–M Schritte.
In den weiteren Durchläufen werden jeweils so viele Rotationen durchgeführt, wie sich Knoten
im jeweils nächst kleineren ausgeglichenen vollen Baum befinden:
lg(M +1)−1
(2
lg(M +1)−1
−1) + (2
lg(M +1)−2
−1)...+ 7 + 3 + 1 =
∑ (2
i
−1) = M − lg(M + 1) Da M die Knoten-
i=1
Damit ergibt sich insgesamt folgende Anzahl an Rotationen (Rechenschritte):
€
N − M + (M − lg(M + 1)) = N − lg(M + 1) = N − #lg(N + 1)$
anzahl des nächst
kleineren vollständig
gefüllten Baumes
ist, kann lg(M+1)
durch lg(N+1)
ersetzt werden.
Konsequenz
€ weist die komplette Neubalancierung eines Baumes eine Zeitkomplexität von O(N) auf.
Insgesamt
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 405
Ende der Vorlesung
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 406
Herunterladen