Binary Search Trees

Week 9, Monday

March 2, 2026

d-ary Tree Definition

A d-ary tree T is either:

  • _______________________________________

OR

  • _______________________________________

Binary Tree Height

height(r) – length of longest path from node r to a leaf

+ * 4 2 3 5

Given a binary tree T, height(T) is


_______________________________________


_______________________________________


Height and Node Count

Question: What’s the maximum number of nodes, \(N(h)\), for a binary tree of height \(h\)?

Height Max Nodes
0 1
1 3
2 7
3 15
h ?

Question: What’s the least height for a tree of \(n\) nodes?

Why Height Matters

Many tree operations take time proportional to height:

  • Finding a node
  • Inserting a node
  • Deleting a node

If height is \(O(\log n)\): these are fast (\(O(\log n)\))

If height is \(O(n)\): these are slow (\(O(n)\))

Goal: Keep trees short!!

Back to Wordle

Recall our decision tree…

  • Height: worst-case # of guesses
  • Goal: minimize the height

decision trees model any sequence of choices where each choice narrows down possibilities.

BUT…

The Dictionary Problem

We want to store key-value pairs with fast operations:

  • insert(key, value): Add a new entry
  • find(key): Look up a value by key
  • remove(key): Delete an entry

Python’s dict does this in O(1) expected time using hashing.

Can we do it with a tree?

Problem: In an arbitrary tree, where should a key go?

If I want to find 25, where do I look? If I want to insert 37, where should I put it?

42 17 8 99 3 56

What Do You Notice?

The Binary Search Tree Property

A Binary Search Tree (BST) is a binary tree where, for every node \(r\):

  • \(x \in r.\text{left} \Rightarrow x.\text{key} < r.\text{key}\)
  • \(x \in r.\text{right} \Rightarrow x.\text{key} > r.\text{key}\)
  • \(r.\text{left}\) is a BST
  • \(r.\text{right}\) is a BST
30 15 45 8 22 40

Implementation

from dataclasses import dataclass

@dataclass
class BSTNode:
    key: int 
    # value: valueType
    left: 'BSTNode' = None
    right: 'BSTNode' = None

Each node stores a key and left/right children.

BST Class: Find

@dataclass
class BST:
    root: 'BSTNode' = None

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

    def _find(self, node: BSTNode, key: int) -> BSTNode:
        if (node is None) or (key == node.key):
            return node
        elif key < node.key:
            return self._find(node.left, key)
        else:
            return self._find(node.right, key)

Running time: O(_____)

Why the Helper Function?

find(key) is the public interface — users call tree.find(25)

_find(node, key) is the recursive helper — it needs to know where in the tree we are

def find(self, key):
    return self._find(self.root, key)  # Start at root

The helper takes a node parameter so it can recurse on subtrees.

This pattern is common for recursive solutions on data structures.

BST Class: Insert

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

def _insert(self, node, key):
    if node is None: # we can insert here!!
        return BSTNode(key)
    if key < node.key:
        node.left = self._insert(node.left, key)
    elif key > node.key:
        node.right = self._insert(node.right, key)
    # If key == node.key, it's a duplicate; do nothing
    return node

Running time: O(height)

Building a BST

Draw the resulting tree.

tree = BST()
for key in [38, 13, 51, 10, 25, 40, 84]:
    tree.insert(key)

Summary: Binary Search Trees

  • BST property: left < root < right (recursively)
  • Find: Binary search down the tree
  • Insert: Find where it belongs, add as leaf
  • Running time: O(height)
  • Best case: balanced tree → O(log n)
  • Worst case: degenerate tree → O(n)

What’s Next

Tuesday: BST Removal

  • Deleting a key is trickier than inserting
  • Three cases: leaf, one child, two children
  • The “inorder predecessor” strategy

Wednesday: Balanced Trees

  • How do we keep a BST balanced?
  • AVL trees and the guarantee of O(log n) height

Practice Problems

  1. Draw the BST that results from inserting: 5, 3, 7, 2, 4, 6, 8
  2. Draw the BST that results from inserting: 2, 3, 4, 5, 6, 7, 8
  3. What is the inorder traversal of each tree?
  4. Which tree is more efficient for searches? Why?