Löschen in binärer Suchbaum?

stimmen
0

Ich lese über den binären Baumknoten - Algorithmus in dem Buch verwendet löschen Datenstrukturen und Algorithmen: Kommentierte Referenz mit Beispielen

auf Seite 34, Fall 4 (Löschen Knoten, die beiden rechten und linken Unterbäumen), folgenden Algorithmus beschrieben in dem Buch sieht nicht funktioniert, wahrscheinlich kann ich mich irren mir jemand helfen könnte, was mir fehlt.

//Case 4
get largestValue from nodeToRemove.Left
FindParent(largestValue).Right <- 0
nodeToRemove.Value<-largestValue.Value

Wie funktioniert die folgende Zeile löscht den größten Wert von Unterbaum FindParent(largestValue).Right <- 0

Veröffentlicht am 29/06/2010 um 21:09
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
1

Die Idee ist, einfach aus dem größten Knoten auf der linken Seite den Wert zu nehmen und es an den Knoten zu bewegen, der gelöscht wird, das heißt, nicht den Knoten überhaupt nicht löschen, ersetzen Sie einfach seinen Inhalt. Dann stutzen Sie den Knoten mit dem Wert aus Sie in den „gelöschten“ Knoten verschoben. Dies hält die Baum-Ordnungs mit jedem Wert des Knotens größer als all seine Kinder verlassen und kleiner als alle seine richtige Kinder.

Beantwortet am 29/06/2010 um 21:16
quelle vom benutzer

stimmen
1

Wenn ich den Pseudo-Code zu verstehen, es funktioniert im allgemeinen Fall, aber nicht in dem „einem Knoten im linken Unterbaum“ Fall. Nizza zu fangen.

Es ersetzt effektiv die node_to_remove mit largest_value davon linken Unterbaum ist (auch nullt den alten largest_value Knoten).

Beachten Sie, dass in einem BST, wird der linke Unterbaum von node_to_remove alle als node_to_remove kleiner sein. Der rechte Teilbaum von node_to_remove werden alle größer als node_to_remove. Wenn Sie also den größten Knoten in dem linken Unterbaum nehmen, wird es die unveränderliche bewahren.

Wenn dies ein „ein Knoten im Unterbaum Fall“ ist, wird es den rechten Teilbaum statt zerstören. Lame :(

Wie Vivin weist darauf hin, es scheitert auch linke Kinder von largestNode wieder zu befestigen.

Beantwortet am 29/06/2010 um 21:16
quelle vom benutzer

stimmen
6

seine in Ordnung Nachfolgeknoten oder dessen in Ordnung Vorgängerknoten Wenn ein Knoten mit zwei Kindern zu löschen, können Sie entweder wählen. In diesem Fall wird es zu finden, die die größten Wert in dem linken Unterbaum (dh die am weitesten rechts stehenden Kind seines linken Unterbaumes), was bedeutet, dass es den Knotens in Ordnung Vorgängerknoten findet.

Sobald Sie den Ersatzknoten finden, die Sie nicht wirklich löschen Sie den Knoten gelöscht werden. Stattdessen nehmen Sie den Wert aus dem Nachfolgeknoten und speichern diesen Wert in den Knoten , den Sie löschen möchten. Anschließend löschen Sie den Nachfolgerknoten. So erhalten Sie die binäre Suchbaum - Eigenschaft Dabei da Sie sicher sein können , dass der Knoten , den Sie ausgewählt wird einen Wert haben, der niedriger als die Werte aller Kinder in den ursprünglichen Knoten des linken Unterbaum ist, und größer , dass als die Werte , aller Kinder in den ursprünglichen Knoten des rechten Unterbaum.

BEARBEITEN

Nach der Lektüre Ihrer Frage ein wenig mehr, ich glaube, ich habe das Problem gefunden zu haben.

Normalerweise , was Sie zusätzlich zu der haben deleteFunktion ist eine replaceFunktion, die den fraglichen Knoten ersetzt. Ich glaube , Sie müssen diese Codezeile ändern:

FindParent(largestValue).Right <- 0

zu:

FindParent(largestValue).Right <- largestValue.Left

Wenn der largestValueKnoten kein linkes Kind hat, bekommen Sie einfach nulloder 0. Wenn es ein linkes Kind hat, wird das Kind ein Ersatz für den largestValueKnoten. Also du hast recht; der Code braucht nicht berücksichtigt das Szenario , dass der largestValueKnoten ein linkes Kind haben könnte.

Ein weiterer EDIT

Da Sie nur einen Ausschnitt gepostet haben, bin ich nicht sicher , was der Kontext des Codes ist. Aber die Schnipsel wie geschrieben scheint das Problem haben Sie vorschlagen (den falschen Knoten ersetzen). Normalerweise gibt es drei Fälle, aber ich merke , dass der Kommentar in Ihrem Snippet sagt //Case 4(so vielleicht gibt es einigen anderen Kontext).

Zuvor erwähnte ich auf die Tatsache , dass deletein der Regel mit einem kommt replace. Wenn Sie also das finden largestValueKnoten, löschen Sie es nach den beiden einfachen Fällen (Knoten ohne Kinder, und der Knoten mit einem Kind). Also , wenn Sie an Pseudo-Code suchen einen Knoten mit zwei Kindern zu löschen, ist es das , was Sie tun:

get largestValue from nodeToRemove.Left
nodeToRemove.Value <- largestValue.Value

//now replace largestValue with largestValue.Left    

if largestValue = largestValue.Parent.Left then   
   largestValue.Parent.Left <- largestValue.Left //is largestValue a left child?
else //largestValue must be a right child
   largestValue.Parent.Right <- largestValue.Left

if largestValue.Left is not null then
   largestValue.Left.Parent <- largestValue.Parent

Ich finde es seltsam, dass ein Datenstrukturen und Algorithmen Buch würde diesen Teil auslassen, also bin ich geneigt zu glauben, dass das Buch weiter die Löschung in ein paar mehr Fälle aufgeteilt hat (da es drei Standardfälle sind), um es einfacher zu verstehen.

Um zu beweisen, dass der obige Code funktioniert, sollten Sie die folgenden Baum:

  8
 / \
7   9

Nehmen wir an , die Sie löschen möchten 8. Sie versuchen , finden largestValueaus nodeToRemove.Left. Dies gibt Ihnen 7da den linken Unterbaum nur ein Kind hat.

Dann tun Sie:

nodeToRemove.Value <- largestValue.Value

Was bedeutet:

8.value <- 7.Value

oder

8.Value <- 7

So, jetzt Ihr Baum sieht wie folgt aus:

  7
 / \
7   9

Sie müssen sich des Ersatzknoten loszuwerden und so wirst du ersetzen largestValuemit largestValue.Left(was null). Also zuerst finden Sie heraus , welche Art von Kind 7ist:

if largestValue = largestValue.Parent.Left then

Was bedeutet:

if 7 = 7.Parent.Left then

oder:

if 7 = 8.Left then

Da 7heißt 8‚s linkes Kind, ersetzen müssen 8.Leftmit 7.Right( largestValue.Parent.Left <- largestValue.Left). Da 7keine Kinder hat, 7.Leftist null. So largestValue.Parent.Leftwird auf null zugewiesen (was effektiv sein linkes Kind entfernt). Dies bedeutet also , dass Sie mit dem folgenden Baum am Ende:

  7
   \
    9
Beantwortet am 29/06/2010 um 21:17
quelle vom benutzer

stimmen
0

Es kann mehr Sinn machen , wenn Sie auf das Aussehen der Wikipedia nehmen auf diesem Teil des Algorithmus:

Löschen eines Knotens mit zwei Kindern : Rufen Sie den Knoten gelöscht „N“ werden. Löschen N. nicht Stattdessen wählen Sie entweder seinen in Ordnung Nachfolgeknoten oder dessen in Ordnung Vorgängerknoten, „R“. Ersetzen Sie den Wert von N mit dem Wert von R, dann löscht R. (Anmerkung: R selbst hat bis zu einem Kind.)

Beachten Sie, dass der gegebene Algorithmus die In-Order-Vorgängerknoten auswählt.

Edit: was die Möglichkeit zu fehlen scheint, dass R (Wikipedia Terminologie zu verwenden) hat ein Kind. Eine rekursive löschen könnte besser funktionieren.

Beantwortet am 29/06/2010 um 21:20
quelle vom benutzer

stimmen
1

Ich glaube, Sie benötigen, um zu klären, was nicht funktioniert.

Ich werde versuchen, das Konzept des Löschens in einem binären Baum zu erklären, falls das hilft.

Nehmen wir an , dass Sie einen Knoten im Baum, die zwei Knoten untergeordnet sind, die Sie löschen möchten. lets in der unten stehenden Baum sagen , dass Sie Knoten b löschen möchten
           ein
         / \
       b c
     / \ / \
   d e f g

Wenn wir einen Knoten löschen müssen wir von ihr abhängigen Knoten wieder zu befestigen.

dh. Wenn wir b löschen müssen wir Knoten d und e wieder zu befestigen.

Wir wissen, dass die linken Knoten sind kleiner als die richtigen Knoten in Wert und dass die übergeordneten Knoten zwischen den linken und rechten Knoten s in Wert. In diesem Fall d <b und b <e. Dies ist Teil der Definition eines binären Baum.

Was ist etwas weniger offensichtlich ist, dass e <a. Dies bedeutet also, dass wir b mit e ersetzen können. Jetzt haben wir e wir d wieder zu befestigen müssen wieder angebracht.

Wie zuvor d <e angegeben, so können wir e als linken Knoten e befestigen.

Die Löschung ist nun abgeschlossen.

(Btw Der Prozess einen Knoten des Bewegens des Baumes und Neuanordnung der abhängigen Knoten in dieser Art und Weise, wird als die Förderung eines Knotens bekannt. Sie könnten auch einen Knoten zu löschen, ohne andere Knoten fördern können.)


           a
         / \
       d c
         \ / \
          e f g

Beachten Sie, dass es eine andere völlig legitime Ergebnis ist der Knoten b von deleteing. Wenn wir wählten Knoten d anstelle des Knotens e fördern würde der Baum so aussehen.


           a
         / \
       e c
     / / \
   d f g

Beantwortet am 29/06/2010 um 21:44
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more