Quando si elimina un nodo con due figli, è possibile scegliere il suo nodo in ordine successore o il suo in-ordine nodo predecessore. In questo caso è trovare il valore più grande nel sotto-albero a sinistra (nel senso che il bambino più a destra del suo sinistro sotto-albero), il che significa che sta trovando in ordine nodo predecessore del nodo.
Una volta trovato il nodo sostitutivo, in realtà non cancella il nodo da cancellare. Invece si prende il valore dal nodo successore e memorizzare tale valore nel nodo che si desidera eliminare. Poi, si elimina il nodo successore. In tal modo a conservare la proprietà di ricerca-albero binario dal momento che si può essere sicuri che il nodo selezionato avrà un valore che è inferiore ai valori di tutti i bambini della sinistra sub-albero del nodo originale, e una maggiore che rispetto ai valori di tutti i bambini a destra sotto-albero del nodo originale.
MODIFICARE
Dopo aver letto la tua domanda un po 'più, credo di aver trovato il problema.
In genere ciò che avete in aggiunta alla deletefunzione è una replacefunzione che sostituisce il nodo in questione. Penso che è necessario modificare questa riga di codice:
FindParent(largestValue).Right <- 0
a:
FindParent(largestValue).Right <- largestValue.Left
Se il largestValuenodo non ha un figlio sinistro, è sufficiente ottenere nullo 0. Se non avere un figlio a sinistra, quel bambino diventa un sostituto per il largestValuenodo. Quindi hai ragione; il codice non prende in considerazione lo scenario che il largestValuenodo potrebbe avere un figlio sinistro.
Un altro EDIT
Dal momento che hai postato solo un frammento, non sono sicuro di quello che il contesto del codice è. Ma il frammento come pubblicato sembra avere il problema suggerisci (che sostituisce il nodo sbagliato). Di solito, ci sono tre casi, ma noto che il commento nel vostro frammento dice //Case 4(così forse c'è qualche altro contesto).
In precedenza, ho accennato al fatto che deletedi solito viene fornito con una replace. Quindi, se si trova il largestValuenodo, lo si elimina secondo i due casi semplici (nodo senza figli, e il nodo con un bambino). Quindi, se stai guardando pseudo-codice per eliminare un nodo con due figli, questo è ciò che farete:
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
Trovo strano che uno Strutture Dati e algoritmi libro sarebbe lasciare fuori questa parte, quindi sono propenso a pensare che il libro ha ulteriormente dividere la cancellazione in un paio di casi (dato che ci sono tre casi standard) per rendere più facile capire.
Per dimostrare che il codice precedente funziona, si consideri il seguente albero:
8
/ \
7 9
Diciamo che si desidera eliminare 8. Si tenta di trovare largestValueda nodeToRemove.Left. Questo ti dà 7in quanto il sub-struttura a sinistra ha un solo figlio.
Poi si fa:
nodeToRemove.Value <- largestValue.Value
Che significa:
8.value <- 7.Value
o
8.Value <- 7
Così ora il vostro albero assomiglia a questo:
7
/ \
7 9
È necessario sbarazzarsi del nodo di sostituzione e così si sta andando a sostituire largestValuecon largestValue.Left(che è null). Quindi, prima di scoprire che tipo di bambino 7è:
if largestValue = largestValue.Parent.Left then
Che significa:
if 7 = 7.Parent.Left then
o:
if 7 = 8.Left then
Dal momento che 7non è in 8figlio sinistro s', necessario sostituire 8.Leftcon 7.Right( largestValue.Parent.Left <- largestValue.Left). Dal momento che 7non ha figli, 7.Leftè nullo. Quindi, largestValue.Parent.Leftviene assegnato a null (che rimuove efficacemente il suo figlio sinistro). Quindi questo significa che si finisce con la seguente struttura:
7
\
9