Vorlesung Datenstrukturen Löschen im Suchbaum Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 386 Löschen im binären Suchbaum Löschen im Suchbaum ist komplizierter als Einfügen, denn es können auch innere Knoten betroffen sein. Wir unterscheiden vier Möglichkeiten: 1. Löschen eines Blattknotens Der auf den zu löschenden Knoten verweisende Zeiger wird im Elternknoten durch den Nullzeiger ersetzt (logisches Löschen) und der Speicherplatz des Blattknotens freigegeben (physisches Löschen). 2. Löschen eines Knotens mit einem Kind Der Zeiger auf den zu löschenden Knoten wird im Elternknoten durch den Zeiger auf den Kindknoten ersetzt (log. Löschen). Anschließend muss noch der Speicherplatz freigegeben werden (phys. Löschen). 3. Löschen eines Knotens mit zwei Kindern Für diese Situation gibt es keine einfache Lösung, da der Elternknoten die beiden Kindknoten nicht aufnehmen kann. Auf den Folgefolien diskutieren wir zwei Lösungsmöglichkeiten dieses Problems. 4. Löschen des Wurzelknotens Das Löschen der Wurzel wird analog der Situationen 1-3 sinngemäß behandelt. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 387 Löschen durch Verschmelzen (1) Allgemein Diese Methode verschmilzt die beiden Teilbäume des zu löschenden Knotens und hängt den resultierenden Teilbaum an den übergeordneten Knoten. Hauptproblem Der resultierende Teilbaum muss den Kriterien eines Suchbaums genügen. Deshalb ergibt sich die Frage, wie die beiden Teilbäume des zu löschenden Knotens verschmolzen werden müssen. Finden der Einhängeposition Per definitionem ist jeder Wert des linken Teilbaums kleiner als jeder Wert des rechten Teilbaums. Folglich gibt es genau zwei Knoten in den Teilbäumen, an den wir den jeweils anderen Teilbaum suchbaumgerecht anhängen können: • der am weitesten rechts befindliche Knoten des linken Teilbaums • der am weitesten links befindliche Knoten des rechten Teilbaums Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 388 Löschen durch Verschmelzen (2) Einhängeposition ist entweder der am • weitesten rechts befindliche Knoten des linken Teilbaums oder der am • weitesten links befindliche Knoten des rechten Teilbaums Verschmelzen der Teilbäume An den gewählten Knoten hängen wir entweder den • rechten Teilbaum als rechten Nachfolger oder den • linken Teilbaum als linken Nachfolger an Der zu löschende Knoten wird ersetzt durch die • Wurzel des linken Teilbaums oder die • Wurzel des rechten Teilbaums Folglich muss der übergeordnete Knoten entweder mit dem • linken Teilbaum oder mit dem • rechten Teilbaum des zu löschenden Knotens verbunden werden, bevor der Speicherplatz des zu löschenden Knotens endgültig freigegeben werden kann. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 389 Löschen durch Verschmelzen (3) node* deleteByMerging(node* n) { node* temp = n; if ( n ) { if ( n->right == 0 ) n = n->left; else if ( n->left == 0 ) n = n->right; else { temp = n->left; while (temp->right) temp = temp->right; temp->right = n->right; temp = n; n = n->left; } delete temp; } return n; } Dr. Frank Seifert // Funktion verschmilzt nur die Teilbäume des zu löschen// den Knotens n und gibt die noch in den übergeordneten // Baum einzuhängende Teilbaumwurzel zurück // Spezialfall: kein oder ein (linker) Kindknoten // Spezialfall: ein (rechter) Kindknoten // Spezialfall: zwei Kindknoten // (1) // Finde äußersten rechten Knoten des linken Teilbaums (2) // Hänge rechten Teilbaum an äußersten // rechten Knoten des linken Teilbaums // Linker Teilbaum ersetzt zu löschenden Knoten (3) (4) (5) // Speicherfreigabe des zu löschenden Knotens (6) // Rückgabe des „verschmolzenen“ Teilbaums Vorlesung Datenstrukturen - Sommersemester 2016 Folie 390 Löschen durch Kopieren (1) Allgemein Wir reduzieren die Problematik des Löschens eines Knotens mit zwei Kindknoten auf das Löschen eines Blattknotens oder das Löschen eines Knotens mit lediglich einem Kind. Ablauf Wir ersetzen den Inhalt des zu löschenden Knotens durch den Inhalt des Knotens, dessen Schlüsselwert der direkte Vorgänger oder Nachfolger des zu löschenden Knotens ist. Danach muss der soeben bestimmte Knoten mit dem Vorgängerschlüssel oder Nachfolgerschlüssel gelöscht werden. Dieser ist entweder der am • weitesten rechts liegende Knoten des linken Teilbaums oder der am • weitesten links liegende Knoten des rechten Teilbaums Dieser Knoten ist entweder ein Blatt oder besitzt maximal einen Kindknoten, entweder links oder rechts. Je nach Situation muss dann nur noch eine der beiden (bereits betrachteten) einfachen Löschoperationen durchgeführt werden. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 391 Löschen durch Kopieren (2) node* deleteByCopying( node* n ){ if (n) { node* temp = n; if ( n->right == 0 ) n = n->left; else if ( n->left == 0 ) n = n->right; else { temp = n->left; node* prev = n; while ( temp->right ) { prev = temp; temp = temp->right; } n->data = temp->data; if ( prev == n ) prev->left = temp->left; else prev->right= temp->left; } delete temp; } return n; } Dr. Frank Seifert // Funktion löscht n und gibt einen Verweis auf den // Nachfolgeknoten (in der Regel n selbst) zurück // kein oder ein (linker) Kindknoten // ein (rechter) Kindknoten // (1) // Bestimme äußersten rechten Knoten des linken // Teilbaums und seinen Vorgänger // (2) // (3) Kopieren des nächst kleineren Schlüsselwerts // Wenn linker Kindknoten keinen rechten Nachfolger hat // (4) hänge seinen linken Teilbaum links an den Vater // sonst // (5) hänge seinen linken Teilbaum rechts an den Vater Vorlesung Datenstrukturen - Sommersemester 2016 Folie 392 Vergleich der Löschvarianten (1) Laufzeit Beide Varianten haben die gleiche Laufzeit, denn es muss jeweils der nächst kleinere bzw. nächst größere Knoten eines Teilbaums bestimmt werden. Alle weiteren Operationen sind unabhängig von der Knotenanzahl des Baumes, laufen also in konstanter Zeit. Gestalt des Baumes bei der Methode „Löschen durch Verschmelzen“ Aufgrund der inhärenten Eigenschaft des Anhängens eines Teilbaums an einen anderen kann die Höhe eines Baumes schnell wachsen. Allerdings ist auch eine Verminderung der Höhe (in Abhängigkeit von den zu löschenden Werten) möglich. Leider gibt es keine Garantie für die Gestalt des Baumes nach wiederholtem Löschen. Schlimmstenfalls kann ein äußerst unbalancierter Baum die Folge des Algorithmus sein. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 393 Vergleich der Löschvarianten (2) Gestalt des Baumes bei der Methode „Löschen durch Kopieren“ Da nur Blattknoten entfernt werden, wird die Höhe eines Baumes grundsätzlich nie größer. Allerdings können, vor allem im Zusammenspiel mit darauf folgenden Einfügeoperationen Degenerierungseffekte auftreten. Ursache Verantwortlich ist die Asymmetrie des Löschalgorithmus, da entweder nur im linken oder nur im rechten Teilbaum gelöscht wird. Als Resultat wird entweder nur der linke oder nur der rechte Teilbaum nach vielen Lösch- und Einfügeoperationen größer und „buschiger“ als sein Pendant. Abhilfe Durch alternierendes Löschen zwischen linkem und rechtem Teilbaum wird der Algorithmus symmetrisch und die beschriebenen Probleme obsolet. Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 394 Ende der Vorlesung Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 395