Verwijder in Binary Zoekboom?

stemmen
0

Ik ben het lezen van de binaire boom te verwijderen knooppunt algoritme dat wordt gebruikt in het boek Gegevensstructuren en algoritmen: geannoteerde Reference met Voorbeelden

op pagina 34, case 4 (knooppunt dat zowel links en rechts onder de bomen heeft Delete), volgende algoritme in het boek ziet er niet werkt beschreven, waarschijnlijk ik kan me vergissen kan iemand mij helpen wat ik mis zijn.

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

Hoe werkt de volgende regel verwijdert de grootste waarde van sub boom FindParent(largestValue).Right <- 0

De vraag is gesteld op 29/06/2010 om 21:09
bron van user
In andere talen...                            


5 antwoorden

stemmen
1

Het idee is om gewoon te nemen van de waarde van het grootste knooppunt aan de linkerkant en verplaats het naar het knooppunt dat wordt verwijderd, dat wil zeggen, doe het knooppunt in het geheel niet te verwijderen, vervang de inhoud ervan. Dan snoeien je uit het knooppunt met de waarde die u in de "verwijderd" knooppunt verplaatst. Dit handhaaft de boom bestellen met de waarde elke node groter dan alle van de links kinderen en kleiner dan alle van de juiste kinderen.

antwoordde op 29/06/2010 om 21:16
bron van user

stemmen
1

Als ik de pseudo-code te begrijpen, het werkt in het algemene geval, maar slaagt er niet in de "één knooppunt in de linker deelboom" case. Mooie vangst.

Het vervangt effectief de node_to_remove met largest_value uit het linker deelboom (nullen ook de oude largest_value knooppunt).

Merk op dat in een BST, de linker deelboom van node_to_remove zal alle kleiner zijn dan node_to_remove zijn. De rechter deelboom van node_to_remove alle groter zijn dan node_to_remove zijn. Dus als je het grootste knooppunt te nemen aan de linker deelboom, zal het de invariante behouden.

Als dit een "één knooppunt in de substructuur case", het zal de rechter deelboom in plaats daarvan te vernietigen. lame :(

Zoals Vivin opmerkt, houdt evenmin links kinderen largestNode meer terugplaatsen.

antwoordde op 29/06/2010 om 21:16
bron van user

stemmen
6

Bij het verwijderen van een knooppunt met twee kinderen, kunt u ervoor kiezen de in-order opvolgerknooppunt of de in-order voorganger node. In dit geval is het vinden van de grootste waarde in het linker subboom (dat wil zeggen de meest rechtse kind van zijn linker subboom), wat betekent dat het vinden van het knooppunt in orde vorige knooppunt.

Zodra u de vervangende knooppunt te vinden, je eigenlijk niet te verwijderen het knooppunt te worden verwijderd. In plaats daarvan u de waarde van de opvolger knooppunt te nemen en op te slaan die waarde in het knooppunt dat u wilt verwijderen. Dan moet je de opvolger knooppunt verwijderen. In doen, zodat u de binary search-boom eigendomsrechten te beschermen want je kunt er zeker van zijn dat het knooppunt u gekozen voor een waarde die lager is dan de waarden van alle kinderen in de linker sub-boom van de oorspronkelijke node zal hebben, en groter dan dan de waarden van alle kinderen in de juiste sub-boom van de oorspronkelijke node.

BEWERK

Na het lezen van uw vraag een beetje meer, ik denk dat ik het probleem gevonden.

Typisch wat u in aanvulling op de deletefunctie is een replacefunctie die de knoop in kwestie vervangt. Ik denk dat je nodig hebt om deze regel code te wijzigen:

FindParent(largestValue).Right <- 0

naar:

FindParent(largestValue).Right <- largestValue.Left

Als het largestValueknooppunt een linker kind heeft, je gewoon krijgen nullof 0. Als het heeft een linkse kind, dat kind wordt een vervanger voor de largestValuenode. Dus je hebt gelijk; de code geen rekening wordt gehouden met het scenario dat het largestValueknooppunt een linker kind zou kunnen hebben.

Een andere EDIT

Aangezien u slechts hebt gepost een fragment, ik weet niet zeker wat de context van de code is. Maar het fragment zoals gepubliceerd lijkt om het probleem dat u suggereren (ter vervanging van de verkeerde knooppunt) te hebben. Meestal zijn er drie gevallen, maar ik merk dat het commentaar in uw fragment zegt //Case 4(dus misschien is er een andere context).

Eerder heb ik gezinspeeld op het feit dat deletemeestal wordt geleverd met een replace. Dus als je het gedeelte van largestValueknooppunt u deze verwijderen volgens de twee eenvoudige gevallen (knooppunt zonder kinderen, en het knooppunt met een kind). Dus als u op zoek bent naar pseudo-code om een knooppunt met twee kinderen te verwijderen, dit is wat je gaat doen:

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

Ik vind het vreemd dat een computer algoritmes en datastructuren boek zou vertrekken uit dit deel, dus ik ben geneigd te denken dat het boek heeft verder opgesplitst het verwijderen in een paar gevallen (omdat er drie standaard gevallen) om het gemakkelijker te maken begrijpen.

Om te bewijzen dat de bovenstaande code werkt, overweeg dan de volgende boom:

  8
 / \
7   9

Laten we zeggen dat u wilt verwijderen 8. Je probeert te vinden largestValueuit nodeToRemove.Left. Dit geeft u 7, omdat de linker sub-boom heeft slechts één kind.

Dan denk je:

nodeToRemove.Value <- largestValue.Value

Wat betekent:

8.value <- 7.Value

of

8.Value <- 7

Dus nu uw boom ziet er als volgt uit:

  7
 / \
7   9

Je moet om zich te ontdoen van de vervangende knooppunt en dus je gaat vervangen largestValuemet largestValue.Left(wat null). Dus eerst kom je erachter wat voor soort kind 7is:

if largestValue = largestValue.Parent.Left then

Wat betekent:

if 7 = 7.Parent.Left then

of:

if 7 = 8.Left then

Daar 7wil 8linker kind, moet vervangen 8.Leftmet 7.Right( largestValue.Parent.Left <- largestValue.Left). Daar 7heeft geen kinderen, 7.Leftis nul. Dus largestValue.Parent.Leftwordt toegewezen aan null (die effectief verwijdert zijn linker kind). Dit betekent dus dat je eindigt met de volgende boom:

  7
   \
    9
antwoordde op 29/06/2010 om 21:17
bron van user

stemmen
0

Het kan zinvol zijn als je kijkt naar de Wikipedia's nemen op dat deel van het algoritme:

Een knooppunt verwijderen met twee kinderen : Roep de knoop te wissen "N". Laat N. niet in plaats daarvan te verwijderen, kiest u de in-order opvolgerknooppunt of de in-order voorganger knooppunt, "R". Vervang de waarde van N met de waarde van R, verwijder R. (Let op: R zelf heeft tot een kind.)

Merk op dat de gegeven algoritme kiest involgorde vorige knooppunt.

Edit: wat lijkt te ontbreken van de mogelijkheid dat R (terminologie Wikipedia's te gebruiken) heeft een kind. Een recursieve verwijderen misschien beter werken.

antwoordde op 29/06/2010 om 21:20
bron van user

stemmen
1

Ik denk dat je kan nodig zijn om duidelijk te maken wat niet werkt.

Ik zal proberen en het concept van verwijdering uit te leggen in een binaire boom in het geval dat dit helpt.

Laten we aannemen dat u een knooppunt in de boom die twee kind knooppunten die u wilt verwijderen heeft. in de boom onder Laten we zeggen dat u wilt knooppunt b schrappen
           a
         / \
       b c
     / \ / \
   d e f g

Wanneer we een knooppunt te verwijderen moeten we daarvan afhankelijke nodes meer terugplaatsen.

d.w.z. Toen we b verwijderen moeten we weer vast knopen d en e.

We weten dat de linker nodes zijn minder dan de rechter knooppunten in waarde en dat de ouder knooppunten zijn tussen de linker en rechter knooppunt s in waarde. Daarbij d <b en b <e. Dit is onderdeel van de definitie van een binaire boom.

Wat is iets minder voor de hand liggende is dat e <a. Dus dit betekent dat we b kunt vervangen door e. Nu hebben we weer vastgemaakt e we nodig hebben om d terugplaatsen.

Zoals eerder gezegd d <e zodat we hechten e zoals het linker knooppunt van e.

De schrapping is nu voltooid.

(Btw Het proces van het verplaatsen van een knooppunt in de boom en het herschikken van de afhankelijke knooppunten op deze manier staat bekend als het bevorderen van een knooppunt. U kunt ook een knooppunt te bevorderen zonder het verwijderen van andere knooppunten.)


           a
         / \
       d c
         \ / \
          e f g

Merk op dat er een legitiem resultaat van deleteing knooppunt b. Als we ervoor gekozen om te bevorderen knooppunt d in plaats van knooppunt e de boom zou er zo uitzien.


           a
         / \
       o o
     / / \
   d f g

antwoordde op 29/06/2010 om 21:44
bron van user

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