Törlés bináris keresés fán?

szavazat
0

Olvasom a bináris fa törölni csomópont használt algoritmus a könyvben Adatszerkezetek és algoritmusok: magyarázatokkal ellátott referencia példákkal

34. oldal, 4. eset (Csomópont törlése, amely a jobb és bal al fák), a következő algoritmus a könyvben leírt néz nem működik, valószínűleg Lehet, hogy tévedek, tudna valaki segíteni nekem, amit én eltűnt.

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

Hogyan működik a következő sort törli a legnagyobb értéket a sub fa FindParent(largestValue).Right <- 0

A kérdést 29/06/2010 21:09
a forrás felhasználó
Más nyelveken...                            


5 válasz

szavazat
1

Az ötlet az, hogy egyszerűen csak az érték a legnagyobb csomópont a bal oldalon, és mozgassa a csomópont, amely törlésre kerül, azaz, ne törölje a csomópont egyáltalán, csak cserélje ki a tartalmát. Akkor szilva ki a csomópontot értéket beköltözött a „törölve” csomópontot. Ez fenntartja a fa rendelés minden csomópont értéke nagyobb, mint az egészet maradt gyermekek és kisebb, mint az egészet igaz gyerekek.

Válaszolt 29/06/2010 21:16
a forrás felhasználó

szavazat
1

Ha jól értem a pszeudo-kód, működik az általános eset, de nem az „egy csomópont a bal oldali részfa” ügyben. Szép fogás.

Hatékonyan helyettesíti a node_to_remove a largest_value belőle a bal részfa (szintén lenullázza a régi largest_value csomópont).

Figyeljük meg, hogy a BST, a bal részfáját node_to_remove lesz, hogy kisebb, mint node_to_remove. A jobb részfáját node_to_remove lesz mind nagyobb node_to_remove. Így ha a legnagyobb csomópont a bal oldali részfa, azt megőrzi az invariáns.

Ha ez egy „egy csomópontot a részfa ügy”, akkor az tönkre a jobb részfa helyett. Lame :(

Ahogy Vivin rámutat, ez pedig nem visszahelyezni bal gyermekek largestNode.

Válaszolt 29/06/2010 21:16
a forrás felhasználó

szavazat
6

Törlésekor csomópont, két gyermek, akkor sem választhatja meg a rendelésre leszármazott csomópont vagy in-sorrendben megelőző csomópont. Ebben az esetben ez a megállapítás a legnagyobb érték a bal részfa (vagyis a jobb szélső gyermeke bal részfa), ami azt jelenti, hogy ez a megállapítás a csomópont in-sorrendben megelőző csomópont.

Miután megtalálta a csere csomópont, akkor valójában nem törli a törlendő csomópontra. Ehelyett az értéke a leszármazott csomópont és tárolja az értéket a csomópont a törölni kívánt. Ezután törölje a leszármazott csomópont. Ezzel biztosíthatja a bináris keresési fa tulajdonság, mert akkor biztos lehet benne, hogy a csomópont kiválasztott lesz és ez az érték alacsonyabb, mint az értékek minden gyerek az eredeti csomópont bal al-fa, illetve több, mint az értékek az összes gyerek az eredeti csomópont jobb al-fa.

EDIT

Miután elolvasta a kérdést egy kicsit, azt hiszem, megtaláltam a problémát.

Általában mi van amellett, hogy a deletefüggvény egy replacefüggvényt, amely helyettesíti a kérdéses csomópont. Azt hiszem, meg kell változtatni ezt a sort:

FindParent(largestValue).Right <- 0

nak nek:

FindParent(largestValue).Right <- largestValue.Left

Ha a largestValuecsomópont nem rendelkezik a bal gyerek, akkor egyszerűen kap nullvagy 0. Ha mégis van egy balra gyermek, hogy a gyermek válik helyettesíti a largestValuecsomópont. Tehát igazad van; A kód nem veszi figyelembe a forgatókönyv, hogy a largestValuecsomópont lehet, hogy egy baloldali gyermek.

Tovább EDIT

Mivel már csak írt egy darabot, nem vagyok biztos benne, mi az összefüggésben a kód. De a részlet, mint kiküldött tűnik, hogy a probléma azt sugallják (felváltva a rossz csomópont). Általában három esetben, de észreveszem, hogy a megjegyzés a részlet azt mondja //Case 4(így talán van más kontextusban).

Korábban utaltam arra, hogy deleteáltalában jön egy replace. Tehát, ha úgy találja, a largestValuecsomópontot, akkor törli azt megfelelően két egyszerű esetekben (node gyermek nélkül, és a node egy gyerek). Tehát, ha nézi pszeudo-kód törölni egy csomópont, két gyerek, ez az, amit megteszek:

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

Találom furcsának, hogy egy adatstruktúrák és algoritmusok könyv lenne kihagyni ezt a részt, így hajlok azt gondolni, hogy a könyv további szét a törlést egy pár esetben (mivel van három normál esetben), hogy könnyebben megért.

Annak bizonyítására, hogy a fenti kód működik, vegye figyelembe a következő fa:

  8
 / \
7   9

Tegyük fel, hogy a törölni kívánt 8. Megpróbálja megtalálni largestValuere nodeToRemove.Left. Ez adja meg 7, mivel a bal részfa csak egy gyermeke van.

Akkor te:

nodeToRemove.Value <- largestValue.Value

Ami azt jelenti:

8.value <- 7.Value

vagy

8.Value <- 7

Tehát most a fát így néz ki:

  7
 / \
7   9

Be kell, hogy megszabaduljon a csere csomópont és így fogsz cserélni largestValueaz largestValue.Left(ami null). Tehát először megtudja, milyen gyerek 7is:

if largestValue = largestValue.Parent.Left then

Ami azt jelenti:

if 7 = 7.Parent.Left then

vagy:

if 7 = 8.Left then

Mivel 7jelentése 8„s bal fia, ki kell cserélni 8.Lefta 7.Right( largestValue.Parent.Left <- largestValue.Left). Mivel 7nincs gyermeke, 7.Leftnull. Így largestValue.Parent.Leftlesz rendelve null (amely hatékonyan távolítja el a bal fia). Tehát ez azt jelenti, hogy a végén a következő fa:

  7
   \
    9
Válaszolt 29/06/2010 21:17
a forrás felhasználó

szavazat
0

Lehet, hogy több értelme, ha megnézi az Wikipédia veszi, hogy része az algoritmus:

Törlése csomópont, két gyermek : Hívja a törlendő csomópontra „N”. Ne törölje N. helyett válassza vagy az in-order leszármazott csomópont vagy in-sorrendben megelőző csomópont, „R”. Cserélje az N értéke a R értékét, majd törölje R. (Megjegyzés: R önmagában akár egy gyerek.)

Vegye figyelembe, hogy az adott algoritmus választja az in-sorrendben megelőző csomópont.

Edit: mi úgy tűnik, hogy hiányzik a lehetőséget, hogy az R (a Wikipédia terminológiájával) egy gyermeke van. A rekurzív törölni lehet jobban működnek.

Válaszolt 29/06/2010 21:20
a forrás felhasználó

szavazat
1

Azt hiszem, akkor lehet, hogy tisztázza, hogy mi nem működik.

Megpróbálom elmagyarázni fogalmának törlését egy bináris fa esetén ez segít.

Tételezzük fel, hogy van egy csomópont a fa, amely két gyermek csomópontok hogy törölni szeretné. A fa alatti mondjuk, hogy törölni szeretné a B csomópont
           a
         / \
       b c
     / \ / \
   d e f g

Amikor töröl egy csomópontot meg kell visszahelyezni a függő csomópontok.

azaz. Amikor töröl b meg kell visszahelyezni csomópontok d és e.

Tudjuk, hogy a bal oldali csomópont kevesebb, mint a megfelelő csomópontok érték, és hogy a szülő csomópontok között a bal és a jobb csomópont s értéket. Ebben az esetben a d <b és b <e. Ez része a meghatározása a bináris fa.

Mi valamivel kevésbé nyilvánvaló, hogy az e <a. Tehát ez azt jelenti, hogy lehet cserélni b az e. Most már visszazárni e meg kell visszahelyezni d.

Amint azt korábban d <e így is csatolja e, mint a bal csomópontjában e.

A törlés befejeződött.

(Mellesleg a folyamat halad a csomópont a fát és átrendezve a függő csomópontok ebben divat ismert előmozdítása csomópont. Azt is elősegíti a csomópont törlése nélkül más csomópontok).


           a
         / \
       d c
         \ / \
          e f g

Vegyük észre, hogy van egy másik teljesen jogos eredményét deleteing csomópont b. Ha úgy döntött, hogy támogassák node d helyett csomópont e a fa így nézne ki.


           a
         / \
       e c
     / / \
   d f g

Válaszolt 29/06/2010 21:44
a forrás felhasználó

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