Al eliminar un nodo con dos hijos, puede elegir su nodo en el orden sucesor o su nodo predecesor en orden. En este caso se trata de encontrar el valor de los más grandes del sub-árbol de la izquierda (es decir, el hijo más a la derecha de su izquierda sub-árbol), lo que significa que es encontrar el nodo predecesor en el orden del nodo.
Una vez que encuentre el nodo de sustitución, que en realidad no elimina el nodo que desea eliminar. En su lugar se toma el valor del nodo sucesor y almacenar ese valor en el nodo que desea eliminar. A continuación, elimina el nodo sucesor. Al hacerlo a preservar la propiedad de búsqueda de árbol binario ya que se puede estar seguro de que el nodo seleccionado tendrá un valor que es inferior a los valores de todos los niños de izquierda sub-árbol del nodo original, y mayor que la de los valores de todos los niños en la derecha sub-árbol del nodo original.
EDITAR
Después de leer su pregunta un poco más, creo que he encontrado el problema.
Normalmente lo que tiene, además de la deletefunción es una replacefunción que sustituye al nodo en cuestión. Creo que se necesita para cambiar esta línea de código:
FindParent(largestValue).Right <- 0
a:
FindParent(largestValue).Right <- largestValue.Left
Si el largestValuenodo no tiene un hijo izquierdo, sólo tiene que obtener nullo 0. Si tiene un hijo izquierdo, ese niño se convierte en un reemplazo para el largestValuenodo. Así que tienes razón; el código no tiene en cuenta el escenario que el largestValuenodo puede tener un hijo izquierdo.
otra EDITAR
Dado que sólo se ha publicado un fragmento, no estoy seguro de lo que el contexto del código es. Pero como el fragmento publicado parece tener el problema que usted sugiere (en sustitución del nodo incorrecto). Por lo general, hay tres casos, pero noto que el comentario en el fragmento dice //Case 4(lo que tal vez hay algún otro contexto).
Anteriormente, he aludido al hecho de que deletepor lo general viene con una replace. Así que si usted encuentra el largestValuenodo, lo elimina de acuerdo con los dos casos simples (nodo sin hijos, y nodo con un niño). Así que si usted está buscando en pseudo-código para eliminar un nodo con dos hijos, esto es lo que va a hacer:
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
Me resulta extraño que una Estructura de Datos y libro Algoritmos dejarían en esta área, por lo que me inclino a pensar que el libro se ha dividido la eliminación en unas pocas más casos (ya que hay tres casos estándar) más para que sea más fácil entender.
Para probar que el código anterior funciona, considere el siguiente árbol:
8
/ \
7 9
Digamos que desea eliminar 8. Intenta encontrar largestValuea partir nodeToRemove.Left. Esto le da 7desde la izquierda sub-árbol sólo tiene un hijo.
Entonces haces:
nodeToRemove.Value <- largestValue.Value
Lo que significa:
8.value <- 7.Value
o
8.Value <- 7
Así que ahora su árbol se ve así:
7
/ \
7 9
Es necesario deshacerse del nodo de sustitución y por lo que vamos a reemplazar largestValuecon largestValue.Left(lo que es null). Así que primero a averiguar qué tipo de niño 7es:
if largestValue = largestValue.Parent.Left then
Lo que significa:
if 7 = 7.Parent.Left then
o:
if 7 = 8.Left then
Dado que 7es 8hijo izquierdo 's, que tenga que reemplazar 8.Leftcon 7.Right( largestValue.Parent.Left <- largestValue.Left). Dado que 7no tiene hijos, 7.Leftes nulo. Así que largestValue.Parent.Leftse le asigna a nulo (que elimina de forma efectiva su hijo izquierdo). Así que esto significa que usted termina con el siguiente árbol:
7
\
9