views:

1591

answers:

4

I am doing some extra work in my computer science class trying to get better at understanding the logic of data structures. Specifically, I am trying to write a remove function for a sorted binary tree:

private boolean remove(Node cRoot, Object o) {
  if (cRoot == null) {
    return false;
  }
  else if (cRoot.item.equals(o)) { 
    //erase node fix tree
    return true;
  }
  else if (((Comparable)item).compareTo(cRoot.item)<=0){
    return remove(cRoot.lChild, o);
  }
  else { 
     return remove(cRoot.rChild,o);
  }
}

I am unsure how to go about writing the "erase node fix tree" part of the code. Mainly how many cases are there and how do I tackle them?

+2  A: 

The basic pseudo-code for erasing a node from a sorted tree is pretty simple:

  1. erase the node value
  2. find child node with maximum value
  3. make it the root node
  4. if it had children - goto 2 recursively

Basically what you are doing is bubbling nodes up the tree, each time the maximum of the children node in each node, so that in the end you stay with a sorted tree, and only one node missing at the end of the full path you went.

Also - see wikipedia on the subject, they have some sample code in C as well.

Yuval A
The maximal child will only have one or zero children; you don't need to goto 2 recursively. You can simply unlink the maximal child after you've copied his value into the original erasure node.
Blank Xavier
+2  A: 

There are generally two ways of performing a remove on the tree:

First method:

Remove the node, then replace it with either child. Then, resort the tree by doing parent-child swapping until the tree is once again sorted.

The second method:

Traverse the tree to find the next (highest or lowest) value that belongs as the root*, if it is a leaf node, swap that with the root, then trim off the value you want to remove. If it is an internal node, you will have to recursively call remove on that node. Repeat until a leaf node is removed.

*What I mean is, if you convert your BST into a sorted list, then you will want to pick either value to the left or right of the root as the new root. I.e. leftmost child of the right subtree, or right most child of the left subtree.

yx
First method - what happens when a node has children on both sides?
Blank Xavier
Second method - what you want to do is find the next largest node (e.g. right one, then left as far as you can) and swap value with him. He will only have one or zero children, so you can then unlink that element directly. No repetition is required.
Blank Xavier
1st method, you use a convention, either always swap left or right node, and use the other node if one does not exist. 2nd method, not necessarily, its possible that the left most node of the right subtree may have a right sub tree containing values bigger than it.
yx
+1  A: 

In the simple case3 you can use next algorithm:

if(removed node had left child)
{
   place left child instead of removed node;
   most_right = most right leaf in the left subtree;
   move right child of removed node as right child of most_right;
}
else
{
   place right child instead of removed node
}

In more complicated case you may need to rebalance your tree (see AVL trees, http://www.cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html for C++ example)

Alex
PS excuse my English :)
Alex
AVL trees require a rebalancing scan on *any* node removal, except I think where the node is a leaf and the parent, after the removal, has a balance factor of 1 or -1 (e.g. if the node is a leaf and has a brother).
Blank Xavier
A: 

//leaf-delete node //1-child Promote the subtree //2-child case replace the node with either //in order successor or predecessor //left most of the right subtree or //right most of the left subtree

Try formatting your comment as code, it will improve readability.
Blank Xavier