árbol de búsqueda binario java

votos
0

Tengo una pregunta sobre cómo eliminar un niño de un nodo (raíz)? Como no puedo llamar a eliminar, si hago que el hijo sea nulo, ¿se moverán los hijos de ese niño? ¿Me gustaría inicializarlo como nulo? ¿O señalaría al hijo del niño?

Publicado el 31/10/2009 a las 20:40
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
2

En un árbol de búsqueda binaria tradicional, la eliminación de un nodo puede tener diferentes consecuencias dependiendo de cuántos hijos tenga el nodo:

  • Un nodo sin hijos simplemente puede ser eliminado
  • Se puede eliminar un nodo con un hijo y el nodo será reemplazado por su único hijo. Esto se aplica independientemente de si el niño es un niño izquierdo o derecho.
  • Un nodo con dos hijos tiene una regla un poco más complicado: hay que encontrar el sucesor en orden o antecesor en el orden del nodo a eliminar, sustituir el valor del nodo actual con la de su sucesor o el valor de su predecesor, a continuación, eliminar el sucesor o predecesor (de acuerdo con estas reglas).
Respondida el 31/10/2009 a las 20:49
fuente por usuario

votos
0

¿Es esta tarea? No hay nada de malo en eso ... nos gusta ayudar a las personas a aprender en lugar de decirles las respuestas.

Si solo configura el nodo secundario como nulo, perderá toda la información sobre los hijos del niño.

Respondida el 31/10/2009 a las 20:51
fuente por usuario

votos
0

Una clase de árbol estándar conocerá a sus hijos, generalmente atrapados en una matriz o colección: en el caso de un árbol binario, solo tienes dos hijos directos, por lo que una matriz de tamaño fijo funcionará. Debido a eso, generalmente implementan algún tipo de método "removeMe" que el niño llama para ser eliminado de esa lista de niños.

Como se mencionó anteriormente, esto se complica si el niño que está eliminando tiene hijos.

Respondida el 31/10/2009 a las 21:33
fuente por usuario

votos
0

La respuesta de Tim parece mejor. Pero sí, querrás hacer una de estas tres cosas dependiendo de qué tipo de niño sea tu eliminación. Si anula a un niño, sus hijos no avanzarán porque ha perdido la referencia a ellos. En su lugar, querrá determinar si los hijos izquierdos o derechos del niño que quita se deben establecer en el puntero que apunta al niño que quita. Después de establecer el puntero de los nodos anterior (izquierda o derecha) al hijo (izquierdo o derecho) del nodo que está eliminando, ya no tendrá una referencia para ese nodo, por lo que no es necesario establecerlo como nulo (puede hacerlo) Ya no tendrá acceso a él. A menos que haya escrito algún tipo de BST doblemente enlazado, en cuyo caso esa no es la BST clásica.

Respondida el 01/11/2009 a las 00:20
fuente por usuario

votos
0

Este código debe ayudarle

public Node<T> getParentOf(Node<T> child){
    findParentOf(this.root, child);
    return temp;
}

private void findParentOf(Node<T> ROOT, Node<T> child){
    if(ROOT.hasLeft()){
        findParentOf(ROOT.left, child);
    }

    if(ROOT.left == child || root.right == child){
        temp = ROOT;
    }

    if(ROOT.hasRight()){
        findParentOf(ROOT.right, child);
    }
}


private void replaceNode(Node<T> original, Node<T> newNode){
    Node<T> tempParent = getParentOf(original);
    if(original == tempParent.left){
        tempParent.left = newNode;
    }else if(original == tempParent.right){
        tempParent.right = newNode;
    }
}

private void traverseChildrenAndAdd(Node<T> newParent, Node<T> oldParent){
    newParent.insert(oldParent.data);
    if(oldParent.hasLeft()){
        traverseChildrenAndAdd(newParent,oldParent.left);
    }



    if(oldParent.hasRight()){
        traverseChildrenAndAdd(newParent,oldParent.right);
    }
}
private void deleteNode(Node<T> ROOT, Node<T> d){
    if(d.data.compareTo(ROOT.data) < 0){
        deleteNode(ROOT.left, d);
    }else if(d.data.compareTo(ROOT.data) > 0){
        deleteNode(ROOT.right, d);
    }else if(d == this.root){
        if(this.root.hasLeft()){
            traverseChildrenAndAdd(root.left, root.right);
            root = root.left;
        }else if(root.hasRight()){
            root = root.right;
        }else{
            root = null;
        }
    }else{
        if(ROOT.hasLeft()&&ROOT.hasRight()){
            Node<T> successor = getMinNode(ROOT);
            replaceNode(successor, successor.right);
        }else if(ROOT.hasLeft() || ROOT.hasRight()){
            if(ROOT.hasLeft()){
                replaceNode(ROOT, ROOT.left);
            }else{
                replaceNode(ROOT, ROOT.right);
            }
        }else{
            replaceNode(ROOT, null);
        }
    }
}

public void remove(T data){
    deleteNode(this.root, new Node<T>(data));
}
Respondida el 13/02/2011 a las 10:14
fuente por usuario

votos
0

Se puede hacer algo como esto (pseudo código):

Dado un la raíz del árbol "raíz" y el nodo a eliminar o algunos datos "x" hacer lo siguiente

 if x < root
      recurse to left child
 if x > root
      recurse to right child
 else //node found
      find the min item of the node right child //min item should be left most leaf node node
      replace the value of the node you want to delete with min nodes value
      now delete the min node
 return root;

código:

delete(Node root, Object x){
    if(root == null){
        return null;
    }

    if(data < root.data){
        root = delete(root.left);
    }else if(root.data < data){
        root = delete(root.right);
    }else{
        if(root.left != null && root.right != null){
            Object tmp = findMin(root.right);
            root.data = tmp;
            root.right = delete(root.right, tmp);
        }else{
            return (root.left != null) ? root.left : root.right;    
        }
    }
return root;

}

Respondida el 09/09/2014 a las 20:33
fuente por usuario

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