Quick Index

Overview


Node removal is conceptually simple, but tends to require a bit of tinkering, which is fun.

Note that when duplicates are allowed, we delete the first match.

Example for Basic Concepts


Here we look at the basic concepts of removal. Note that we ignore tree balance to simplify the example.

Deletion or removal of a node requires shifting nodes so that order is preserved.

  • Our initial BST for this example
  • Remove node with element 10
  • Because the right subtree (of the removed node) has greater height, shift it up. Node-20 replaces Node-10.
                       50
                       |
          -------------+
          |
          10
     -----+-----
     |          |
     5          20
                 +-----
                      |
                      30
                       +-----
                             |
                             40
  • Remove node with element 20
  • Because the right subtree (of the removed node) has greater height, shift it up. Node-30 replaces Node-20.
                       50
                       |
          -------------+
          |
          20
     -----+-----
     |          |
     5          30
                 +-----
                      |
                      40
  • Remove node with element 30
  • Because the subtrees have equal height, shift up the left subtree. Node-5 replaces Node-30.
                       50
                       |
          -------------+
          |
          30
     -----+-----
     |          |
     5          40
  • Remove node with element 5.
  • The removed node only has a right subtree, so shift it up. N-40 replaces N-5.
                       50
                       |
          -------------+
          |
          5
          +-----
                |
                40
  • Remove node with element 40.
  • The removed node only has no subtrees, so no shifting required.
                       50
                       |
          -------------+
          |
          40
  • Remove node with element 50.
  • The removed node only has no subtrees, so no shifting required.
  • In this case the root was removed.
                       50
                       |
The tree is now empty.
EMPTY TREE

Example for Algorithms


======================================================================
Remove

Remove shares some of the same mechanims used for insert and balancing.

Let's say we are removing the node with key 10.

               100
               /  \
              /    \
             /      \
            /        \
           50         130
          /  \          \
         /    \          \
        /      \          \
       /        \          \
      /          \          \
     /            \          \
    10            80         150
                  /
                 /
                /
               70


We will assume 100 is the root for this example,
but this could also be an internal sub-tree.

Collect all nodes as stack from root to the node we are deleting.
e.g. [100, 50, 10]
Note: if you don't have a stack class handy, any list class will do.

child (to delete): 10
parent: 50
grandparent: 100

Zooming in on parent.removeChild(child)

         50                   50
        /  \                   \
       /    \                   \
      /      \                   \
     /        \                   \
    /          \                   \
   /            \                   \
  10            80                  80
                /                   /
               /                   /
              /                   /
             70                  70

Rebalance

     50
      \
       \                                     70
        \                                   /  \
         \                                 /    \
          \         balance               /      \
           \     ==============>         /        \
           80     (right-left)          50         80
           /
          /
         /
        70

Reset grandparent's left with balanced node (70)

              100
              /  \
             /    \
            /      \
           /        \
          70         130
         /  \          \
        /    \          \
       /      \          \
      /        \          \
     /          \          \
    /            \          \
   50            80         150

==============

Other Considerations

Resetting height

    For cases where the sub-tree (like in the previous example)
    has ancestor nodes above it in the tree, each ancestor
    in the path from the root to the the
    grandparent node (100) should recalculate height,
    which is simply the max of its child heights.

Removing node with children

    If removing a node that has child nodes,
    we can use the similar rotation concepts,
    but with the removal added in.
 
    Say we are removing 10, we could rotate like this:
 
     first rotate left to remove child (5) skew to right
 
                   10                  10
                  /  \                /  \
                 /    \              /    \
                /      \            /      \
               5       40          5       40
                \                 /
                 \               /
                  \             /
                   8           8
 
 
 the new parent         add old right (40)
 (to replace 10)          to new parent
 
        5                      5
       /                      / \
      /                      /   \
     /                      /     \
    8                      8      40


References