Question

I have a question about how would I remove a child from a node (root)? Since I can't call remove, if I make the child null, will the children of that child move up? Like, would I just initialize it as null?? Or would I point to the child's child?

Was it helpful?

Solution

In a traditional binary search tree, removal of a node can have different consequences depending on how many children the node has:

  • A node with no children can simply be removed
  • A node with one child can be removed, and the node will be replaced by its only child. This applies regardless of whether the child is a left or right child.
  • A node with two children has a slightly more complicated rule: you must find the in-order successor or in-order predecessor of the node to be removed, replace the current node's value with its sucessor's or predecessor's value, then delete the successor or predecessor (according to these rules).

OTHER TIPS

Is this homework? Nothing wrong with that... we just like to help people learn rather than tell them the answers.

If you just set the child node to null you'll lose any information about the childs children.

A standard tree class will know its children, usually stuck in an array or Collection - in the case of a binary tree, you've only got two direct children, so a fixed sized array will work. Because of that, they usually implement some sort of "removeMe" method that the child calls to get removed from that list of children.

As mentioned above, this gets complicated if the child you are removing has children.

Tim's answer seems best. But yes you will want to do one of three things depending on what kind of child it is your removing. If you make a child null, the children of it will not move up because you've lost reference to them. Instead, you'll want to determine if the left or right children of the child your removing should be set to the pointer pointing to the child your removing. After you set the previous' nodes pointer (left or right) to the child (left or right) of the node your removing, you wont have a reference anymore to that node, so theres no need to set it to null (you can't access it anymore. Unless you wrote some sort of doubly-linked BST, in which case that's not the classic BST)

This code should help you

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));
}

You can do something like this (pseudo code):

Given a the root of the tree "root" and the node to delete or some data "x" do the following

 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;

code:

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;

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top