I'm trying to follow the BST algorithm in "Data Structures and Algorithms" by Granville Barnett, but I don't understand the node-deletion algorithm it describes below.
Section 3.3 (p. 22)
Removing a node from a BST is fairly straightforward, with four cases to consider:
- the value to remove is a leaf node; or
- the value to remove has a right subtree, but no left subtree; or
- the value to remove has a left subtree, but no right subtree; or
- the value to remove has both a left and right subtree in which case we promote the largest value in the left subtree.
Figure 3.2 (p. 22)
23
/ \
14 31
/
7
\
9
- Case #1 points to node 9.
- Case #2 points to node 7.
- Case #3 points to node 14.
- Case #4 points to node 23.
I interpret the text above for #4 to mean that when we remove 23, we promote 14 to root and make 31 its right child:
14
/ \
7 31
\
9
...but the book's algorithm (from p. 23) for case #4 bamboozles me (I've rewritten it here in Java):
1 boolean remove(T value) {
2 // ...
3
4 // case #4
5 Node largestValueNode = nodeToRemove.left;
6 while (largestValueNode.right != null) {
7 // find the largest value in the left subtree of nodeToRemove
8 largestValueNode = largestValueNode.right;
9 }
10
11 // delete the right child of largestValueNode's parent
12 findParent(largestValueNode.value).right = null;
13 nodeToRemove.value = largestValueNode.value;
14
15 count--;
16 return true; // successful
17}
If I follow the algorithm, the largestValueNode
is node 14, so its parent is node 23. Why does the algorithm nullify the right child of the parent?
Why does line 13 copy the largestValueNode
's value into the node to be deleted?
I would've expected lines 11-13 to be:
11 if (largestValueNode != null)
12 largestValueNode.right = nodeToRemove.right;
13 nodeToRemove.right = null;
EDIT:
The book's algorithm indeed has a bug. The fix is below:
1 boolean remove(T value) {
2 // ...
3
4 // case #4
5 Node largestValueNode = nodeToRemove.left;
6 while (largestValueNode.right != null) {
7 // find the largest value in the left subtree of nodeToRemove
8 largestValueNode = largestValueNode.right;
9 }
10
11 Node p = findParent(largestValueNode.value);
12 if (p != null) {
13 if (nodeToRemove == p)
14 nodeToRemove.left = largestValueNode.left;
15 else
16 p.right = largestValueNode.left;
17 }
18 nodeToRemove.value = largestValueNode.value;
19
20 count--;
21 return true; // successful
22}
count--
, the text has the following line:nodeToRemove.Value = largestValueNode.Value
, which you're missing here. – Dan Nissenbaum