BST Removal

Week 9, Tuesday

March 3, 2026

Recap: BST Operations

We’ve seen find and insert — both O(height).

def find(self, key: int) -> BSTNode:
    return self._find(self.root, key)

def insert(self, key: int):
    self.root = self._insert(self.root, key)

Today: How do we remove a key?

def remove(self, key: int):
    self.root = self._remove(self.root, key)

Binary Search Tree – Remove

T.remove(37)

38 13 51 10 25 84 12 37 66 89 95

T.remove(51)

38 13 51 10 25 84 12 37 66 89 95

Binary Search Tree – Remove

T.remove(38)

38 13 51 10 25 84 12 37 IOP 66 89 95

Binary Search Tree - Remove

38 13 51 10 25 84 12 37 66 89 95
def _remove(self, node, key):
    if node is None:
        return None
    if node.key == key:
        return self._do_removal(node)
    elif key < node.key:
        node.left = self._remove(
            node.left, key)
    else:
        node.right = self._remove(
            node.right, key)
    return node
def _do_removal(self, node):
    if node.left and node.right:
        return self._____child_remove(node)
    else:
        return self._____child_remove(node)

Binary Search Tree - Remove

38 13 51 10 25 84 12 37 66 89 95
def _do_removal(self, node):
    if node.left and node.right:
        return self._two_child_remove(node)
    else:
        return self._zero_one_child_remove(node)
def _zero_one_child_remove(self, node):
    if not node.left:
        return node.right
    else:
        return node.left

Binary Search Tree - Remove

38 13 51 10 25 84 12 37 IOP 66 89 95
def _two_child_remove(self, node):
    iop = self._find_max(node.left)
    node.key = iop.key
    node.left = self._remove_max(node.left)
    return node
def _remove_max(self, node):
    if not node.right:
        return node.left  # remove this node
    node.right = self._remove_max(node.right)
    return node

Try It: Interactive BST

Recap

A dictionary is a structure supporting:

def insert(self, key, data): ...
def find(self, key): ...
def remove(self, key): ...

B_______ S_______ T_____ implementation of a dictionary incurs running time _________ for all of these.

Binary Search Tree

38 13 51 10 25 84 12 37 66 89 95

The algorithms on BST depend on the height (h) of the tree.

The analysis should be in terms of the amount of data (n) the tree contains.

So we need relationships between h and n.

\[h \geq f(n)\]

\[h \leq g(n)\]

Reminder: height(T) is:

  • ______ if T is empty
  • 1 + max{height(TL), height(TR)}, otherwise

Average Case

The height of a BST depends on the order in which the data is inserted into it.

ex. 1 3 2 4 5 7 6 vs. 4 2 3 6 7 1 5

How many different ways are there to insert n keys into a tree?

Average height, over all arrangements of n keys is _____________.

BST Operations Summary

Operation Avg Case Worst Case Sorted Array Sorted List
find
insert
remove
traverse

The Takeaway

BSTs give us O(height) operations.

Lower Bound: Height = O(log n) → fast!

Worst case: Height = O(n) → slow!

Question: Can we guarantee O(log n) height?

Practice Problems

  1. Draw the BST after these operations starting from empty:

    • Insert: 50, 30, 70, 20, 40, 60, 80
    • Remove: 30
  2. In the tree from #1, what is the inorder predecessor of 50?

  3. Remove 50 from the tree. What does the tree look like after?

  4. Write a function find_min that finds the minimum key in a BST.