next up previous index
Next: Enumerations Up: EmptyTree and NodeTree implementations Previous: add   Index


remove

We use a simple approach to removing an item from an EmptyTree

public SearchTree remove(Comparable item) {
    return this;
}
The item is not present, so there is nothing to do. But we have to return a SearchTree, so we just return this.

The problem of removing an item from a NodeTree is quite delicate. The problem is, of course, to maintain the ordering property (S). This means rearranging the tree, and there is no unique solution to this. In general it is desirable to maintain a good balance to the tree. Here we shall just be satisfied to remove the item and maintain the ordering property.

Suppose that we wish to remove the item 21 from the original binary search tree


\begin{picture}(200,190)(-70,0)
\put(0,180){\makebox(0,0){21}}
\put(-60,120){\...
...){20}}
\put(-12,12){\line(2,3){20}}
\put(52,12){\line(-2,3){20}}
\end{picture}
Some item other than 21 will have to be at the root of the new tree, and it will have to be larger than all elements in the current left sub-tree of 21 and smaller than all elements in the current right sub-tree of 21. A simple solution we adopt is to replace 21 by the smallest item in the right sub-tree, and then to delete that item from the right sub-tree, leaving the tree

\begin{picture}(200,190)(-70,0)
\put(0,180){\makebox(0,0){22}}
\put(-60,120){\...
...}}
% put(-12,12)\{ line(2,3)\{20\}\}
\put(52,12){\line(-2,3){20}}
\end{picture}
This is sure to preserve the ordering property. We are left with the tasks of defining supplementary procedures for finding the smallest element in a tree and then deleting that element. But they are both very easy to write. One final point to make is that, if there is no right hand sub-tree, it is very easy to delete the item at the root. You just replace the root by the left sub-tree. So, if the tree had begun as

\begin{picture}(200,60)(-70,120)
\put(0,180){\makebox(0,0){21}}
\put(-60,120){\makebox(0,0){10}}
\par\put(-50,130){\line(1,1){36}}
\end{picture}
we should just have replaced the root by the left hand sub-tree, consisting of the single node 10. Note that we could just as well have gone to work on the left sub-tree, i.e. replace the item by the largest element in its left sub-tree etc. We just choose the right for definiteness.

The code for removing an item from a NodeTree is shown in Figure 8.2

Figure 8.2: A simple removal method for binary search trees.
private Comparable findMin() {
    if (left.isEmpty()) {
        return data;
    } else {
        return ((NodeTree) left).findMin();
    }
}

private SearchTree removeMin() {
    if (left.isEmpty()) {
        return right; 
    } else {
        left = ((NodeTree) left).removeMin();
        return this;
    }
}

public SearchTree remove(Comparable item) {
    int compare = item.compareTo(data);
    if (compare == 0 && right.isEmpty()) {
        return left;
    } else {
        if (compare < 0) {
            left = left.remove(item);
        } else if (compare > 0) {
            right = right.remove(item);
        } else {
            data = ((NodeTree) right).findMin();
            right = ((NodeTree) right).removeMin();
        }
        return this;
    }
}

together with the two auxiliary private methods. You are advised to work through this code, bearing in mind the previous discussion of the algorithm. Note that these procedures have been written recursively. The basic remove method descends recursively through the tree until either an EmptyTree is encountered, or the item is found (compare == 0). If the item is found, either the right subtree at this node is empty, in which case we return the left subtree or, if the right subtree is not empty, the auxiliary methods findMin and removeMin are invoked, which are themselves recursive methods.

Note also the type coercion in, for example,

data = ((NodeTree) right).findMin();
The reason is that the methods findMin and removeMin are only needed for non-empty trees, and we only define them in the NodeTree class. If you were to write
data = right.findMin();
you would get an error message
findMin() not found in class SearchTree
Note also that we only force this type coercion after we have checked that the tree in question is not empty.


next up previous index
Next: Enumerations Up: EmptyTree and NodeTree implementations Previous: add   Index
Peter Williams 2005-06-07