Při odstraňování uzel se dvěma dětmi, můžete si vybrat buď svůj v pořadí následníků uzlu nebo její in-pořadí předchůdce uzlu. V tomto případě je to najít největší hodnotu v levém podstromu (to znamená nejvíce vpravo dítě jejím levém podstromu), což znamená, že je najít uzlu v objednávku předchůdce uzlu.
Jakmile najdete náhradní uzel, nemáte skutečně odstranit uzel, které mají být odstraněny. Namísto toho budete mít hodnotu od nástupnické uzlu a uloží tuto hodnotu do uzlu, který chcete odstranit. Potom odstraňte uzel následníka. Tím zvýšíte binární vlastnost search-tree, protože si můžete být jisti, že uzel jste vybrali bude mít hodnotu, která je nižší než hodnoty ze všech dětí v původní uzel v levém podstromu, a vyšší než než hodnoty ze všech dětí v původní uzel v pravém podstromu.
UPRAVIT
Po přečtení svůj dotaz trochu víc, myslím, že jsem našel problém.
Obvykle to, co máte vedle deletefunkce je replacefunkce, která nahradí uzel v otázce. Myslím, že je třeba změnit tento řádek kódu:
FindParent(largestValue).Right <- 0
na:
FindParent(largestValue).Right <- largestValue.Left
V případě, že largestValueuzel nemá levé dítě, můžete jednoduše dostat nullnebo 0. Pokud tomu tak má levý dítě, že dítě se stane náhradou za largestValueuzlu. Takže máte pravdu; Kód nebere v úvahu scénář, že largestValueuzel může mít levé dítě.
Další EDIT
Vzhledem k tomu, že jste zaslali jen úryvek, nejsem si jistý, co kontext kódu. Ale úryvek as vykázala nezdá se, že mají problém, navrhnout (nahrazení špatně uzel). Obvykle existují tři případy, ale všiml jsem si, že poznámka ve fragmentu říká //Case 4(takže možná tam je nějaký jiný kontext).
Dříve, zmiňoval jsem se k tomu, že deleteobvykle přichází s replace. Takže pokud se vám zdá largestValueuzlu, jej odstranit podle dvou jednoduchých případech (uzel bez dětí, a uzel s jedním dítětem). Takže pokud se díváte na pseudokódem odstranit uzel se dvěma dětmi, to je to, co budete dělat:
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
Připadá mi divné, že datové struktury a algoritmy kniha by vynechat tuhle část, takže se přikláním k názoru, že kniha má dále rozdělit vypuštění do několika dalších případech (protože tam jsou tři standardní případy), aby bylo snazší rozumět.
Dokázat, že výše uvedený kód funguje, zvažte následující stromu:
8
/ \
7 9
Řekněme, že chcete smazat 8. Při pokusu najít largestValueod nodeToRemove.Left. To vám dává 7, protože levá sub-strom má jen jedno dítě.
Pak můžete udělat:
nodeToRemove.Value <- largestValue.Value
Což znamená:
8.value <- 7.Value
nebo
8.Value <- 7
Takže teď váš strom vypadá takto:
7
/ \
7 9
Musíte se zbavit náhradního uzlu, a tak budete nahradit largestValues largestValue.Left(což je null). Takže nejprve zjistit, jaké dítě 7je:
if largestValue = largestValue.Parent.Left then
Což znamená:
if 7 = 7.Parent.Left then
nebo:
if 7 = 8.Left then
Vzhledem k tomu, 7je 8levé dítěte, je třeba nahradit 8.Lefts 7.Right( largestValue.Parent.Left <- largestValue.Left). Vzhledem k tomu 7nemá žádné děti, 7.Leftje nulová. Tak largestValue.Parent.Leftdostane přiděleno na null (který účinně odstraňuje jeho levé dítě). Takže to znamená, že jste skončili s tímto stromem:
7
\
9