Lors de la suppression d'un nœud avec deux enfants, vous pouvez choisir son noeud successeur d'ordre ou son dans l'ordre noeud prédécesseur. Dans ce cas, il est de trouver la valeur la plus élevée dans le sous-arbre gauche (ce qui signifie le droit enfant le plus de son sous-arbre gauche), ce qui signifie qu'il est de trouver dans l'ordre nœud prédécesseur du nœud.
Une fois que vous trouvez le nœud de remplacement, vous ne pas réellement supprimer le nœud à supprimer. Au lieu de cela , vous prenez la valeur du nœud successeur et de stocker cette valeur dans le nœud que vous souhaitez supprimer. Ensuite, vous supprimez le nœud successeur. Ce faisant, vous préservez la propriété binaire recherche d'arbres puisque vous pouvez être sûr que le nœud sélectionné aura une valeur qui est inférieure aux valeurs de tous les enfants sous-arbre gauche du noeud d' origine, et plus que que les valeurs de tous les enfants dans le droit du nœud d' origine sous-arbre.
MODIFIER
Après avoir lu votre question un peu plus, je crois avoir trouvé le problème.
En général ce que vous avez en plus de la deletefonction est une replacefonction qui remplace le nœud en question. Je pense que vous devez changer cette ligne de code:
FindParent(largestValue).Right <- 0
à:
FindParent(largestValue).Right <- largestValue.Left
Si le largestValuenœud ne dispose pas d' un enfant à gauche, vous simplement obtenir nullou 0. Si elle a un enfant laissé, cet enfant devient un remplacement pour le largestValuenœud. Donc , vous avez raison; le code ne prend pas en compte le scénario que le largestValuenœud peut avoir un enfant gauche.
une autre EDIT
Puisque vous avez seulement posté un extrait, je ne suis pas sûr de ce que le contexte du code est. Mais l'extrait comme affiché ne semble pas avoir le problème que vous proposez (remplacer le mauvais nœud). En général, il y a trois cas, mais je remarque que le commentaire dans votre extrait dit //Case 4(alors peut - être il y a un autre contexte).
Plus tôt, je faisais allusion au fait que deletevient habituellement avec replace. Donc , si vous trouvez le largestValuenœud, vous le supprimez selon les deux cas simples (noeud sans enfant, et le noeud avec un enfant). Donc , si vous cherchez à pseudo-code pour supprimer un nœud avec deux enfants, c'est ce que vous allez faire:
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
Je trouve étrange qu'un Structures de données et livre Les algorithmes quitteraient cette partie, donc je suis enclin à penser que le livre a encore divisé la suppression dans quelques autres cas (car il y a trois cas standards) pour le rendre plus facile à comprendre.
Pour prouver que le code ci-dessus fonctionne, considérez l'arbre suivant:
8
/ \
7 9
Disons que vous voulez supprimer 8. Vous essayez de trouver largestValuede nodeToRemove.Left. Cela vous donne 7depuis le sous-arbre gauche n'a qu'un seul enfant.
Ensuite, vous faites:
nodeToRemove.Value <- largestValue.Value
Ce qui signifie:
8.value <- 7.Value
ou
8.Value <- 7
Alors maintenant votre arbre ressemble à ceci:
7
/ \
7 9
Vous devez vous débarrasser du nœud de remplacement et donc vous allez remplacer largestValuepar largestValue.Left( ce qui est null). Alors d' abord vous trouvez ce genre d'enfant 7est:
if largestValue = largestValue.Parent.Left then
Ce qui signifie:
if 7 = 7.Parent.Left then
ou:
if 7 = 8.Left then
Depuis 7est -à- 8enfant gauche de l », besoin de remplacer 8.Leftpar 7.Right( largestValue.Parent.Left <- largestValue.Left). Depuis 7n'a pas d' enfant, 7.Leftest nulle. Alors largestValue.Parent.Leftobtient attribué à null (qui élimine efficacement son enfant à gauche). Cela signifie donc que vous vous retrouvez avec l'arbre ci - dessous:
7
\
9