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?
árbol de búsqueda binario java
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).
¿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.
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.
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.
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));
}
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;
}













