Eliminar en árbol binario de búsqueda?

votos
0

Estoy leyendo a través del algoritmo de árbol binario eliminar nodos utilizados en el libro Estructuras de Datos y Algoritmos: Referencia anotado con ejemplos

en la página 34, el caso 4 (Eliminar nodo que tiene dos árboles sub derecho e izquierdo), siguiendo el algoritmo descrito en el parece que no funciona libro, probablemente, puedo estar equivocado alguien podría ayudarme lo que me falta.

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

¿Cómo funciona la línea siguiente elimina el valor más grande de sub-árbol FindParent(largestValue).Right <- 0

Publicado el 29/06/2010 a las 21:09
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
1

La idea es simplemente tomar el valor del nodo más grande en el lado izquierdo y moverlo al nodo que se va a eliminar, es decir, no elimine el nodo en absoluto, simplemente reemplazar su contenido. A continuación, podar el nodo con el valor que movió en el nodo de "borrado". Esto mantiene el orden de árbol con el valor de cada nodo más grande que toda ella queda niños y más pequeño que todos los niños que es recto.

Respondida el 29/06/2010 a las 21:16
fuente por usuario

votos
1

Si entiendo el pseudo-código, que funciona en el caso general, pero no en el "un nodo en el subárbol izquierdo" caso. Buena atrapada.

Que sustituye eficazmente el node_to_remove con largest_value desde su subárbol izquierdo (también NULLS el nodo largest_value de edad).

Tenga en cuenta que en un BST, el subárbol izquierdo de node_to_remove será todo ser menor que node_to_remove. El subárbol derecho de node_to_remove todo será más grande que node_to_remove. Así que si usted toma el nodo más grande en el subárbol izquierdo, se preservará el invariante.

Si se trata de un "un nodo en el caso sub-árbol", que va a destruir el subárbol derecho en su lugar. :( cojo

Como Vivin señala, también falla para volver a unir los niños izquierdos de largestNode.

Respondida el 29/06/2010 a las 21:16
fuente por usuario

votos
6

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
Respondida el 29/06/2010 a las 21:17
fuente por usuario

votos
0

Se puede tener más sentido cuando nos fijamos en la Wikipedia toma en esa parte del algoritmo:

Eliminación de un nodo con dos niños : Call el nodo a borrar "N". No elimine N. En cambio, elegir bien su nodo sucesor en orden o de su nodo predecesor en orden, "R". Reemplazar el valor de N con el valor de R, a continuación, eliminar R. (Nota: R en sí tiene un máximo de un niño.)

Tenga en cuenta que el algoritmo dado elige el nodo predecesor en orden.

Edit: lo que parece faltar la posibilidad de que R (para usar la terminología de Wikipedia) tiene un hijo. Una eliminación recursiva podría funcionar mejor.

Respondida el 29/06/2010 a las 21:20
fuente por usuario

votos
1

Creo que es posible que necesite para aclarar lo que no funciona.

Voy a tratar de explicar el concepto de supresión en un árbol binario en caso de que esto ayude.

Vamos a suponer que usted tiene un nodo en el árbol que tiene dos nodos hijos que desea eliminar. en el árbol de abajo vamos a decir que quiere eliminar el Nodo B
           un
         / \
       b c
     / \ / \
   d e f g

Cuando borramos un nodo que necesitamos para volver a unir sus nodos dependientes.

es decir. Cuando borramos b necesitamos para volver a unir los nodos D y E.

Sabemos que los nodos de izquierda son menores que los nodos adecuados en valor y que los nodos principales son entre el nodo de izquierda y derecha en el valor de s. En este caso d <b y b <e. Esto es parte de la definición de un árbol binario.

Lo que es un poco menos obvio es que el e <a. Así que esto significa que podemos reemplazar B e. Ahora hemos vuelve a unir e necesitamos para volver a unir d.

Como se dijo antes d <e para que podamos unir e como el nodo izquierda de la dirección.

La deleción se ha completado.

(Por cierto, el proceso de mover un nodo en el árbol y la reordenación de los nodos dependientes de esta manera se conoce como la promoción de un nodo. También puede promover un nodo sin borrar otros nodos.)


           un
         / \
       d c
         \ / \
          e f g

Observe que no es otro resultado perfectamente legítimo de deleteing nodo b. Si elegimos para promover el nodo D en lugar del nodo E el árbol se vería así.


           un
         / \
       e c
     / / \
   d f g

Respondida el 29/06/2010 a las 21:44
fuente por usuario

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