Binary Search Trees

advertisement
Binary Search
Trees
Adding and
Removing
Adding to the Tree
Adding to a binary search tree is fairly straightforward. You will begin
at the root, and as you move down to each node, there are three
cases:
1. The value to be added is equal to the value of the current
node.
2. The value to be added is less than the value of the current
node.
3. The value to be added is greater than the value of the
current node.
Lesser values should always be added to the left subtree while
greater values should always be added to the right subtree. A value
equal to the current node should never be added to the tree. The
tree below was created by adding values 10, 5, 15, 13, 1, 17, 7, 6, 2,
and 9 in that order.
Removing from the Tree
Removing from a binary search tree is much more difficult. There are
many logically correct ways to remove from a tree, but only one
correct way to pass the test driver. Carefully consider the following
cases when writing your remove method.
Case 1: The Leaf Node
The node to be removed is a leaf node. A leaf node has no
children. Nodes 2, 6, 9, 13, and 17 are all leaf nodes because they
have neither a left child nor a right child.
In the example below, the leaf node 2 is removed. Node 1’s right
child is assigned to NULL.
Before
After
Case 2: The Inorder Predecessor
The inorder predecessor is the rightmost node in the left subtree of
the node to be removed. The node to be removed should be
replaced with its inorder predecessor. This allows us to remove
nodes with children without rebuilding the entire tree.
The node to be removed (node 10) is not a leaf, so there is more
work to do. The inorder predecessor in this case is node 9, so we set
node 10’s value to 9 and remove node 9 easily because it is a leaf.
Before
After
Case 3: The Inorder Predecessor
with a Left Child
An inorder predecessor will never have a right child, but it might
have a left child. In this case, the predecessor’s parent adopts the
predecessor’s left child as its right child.
In this case, we are removing node 9. The predecessor is node 7, but
7 has a child. When we remove node 7, we must reassign node 5’s
right child to point to node 6.
Before
After
Case 4: The Predecessor is the
Left Child
When finding the inorder predecessor, you first move to the left child of the
node to be removed, then move as far right as possible. If that left child does
not have a right child, then it is the inorder predecessor. Like before, the
node to be removed takes the predecessor’s value. The node to be
removed then adopts the predecessor’s left child as its own left child.
In this example, we want to remove node 15. We look to node 13 to find the
inorder predecessor; node 13 has no right child. In this case, we assign node
15 a value of 13 and set node 15’s left child to the child of 13, NULL in this
case.
Before
After
Case 5: The Missing Predecessor
If the node to be removed does not have a left child, there is no
inorder predecessor. In this case, the node to be removed takes the
value of its right child and then adopts its right child’s children as its
own children.
In this case, we want to remove node 13, which has no left child.
We assign node 13 a value of 17 and set 13’s left child to node 16
and its right child to node 18.
Before
After
Download