Thuta Learning
IntermediateProgrammingintermediate

Binary Search Trees — O(log n) Search

What you'll walk away with

  • Explain the core ideas behind Binary Search Trees — O(log n) Search
  • Run the sample Python code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

A binary search tree (BST) adds one invariant on top of a plain binary tree: for every node, all values in its left subtree are smaller and all values in its right subtree are larger. That invariant turns search into binary search performed on a tree shape — compare the target against the current node, then descend only into the left or right subtree depending on the comparison, eliminating half the remaining candidates at every step. For a balanced tree this makes the height O(log n), so both search and insert are O(log n). But that guarantee depends entirely on the tree's shape: inserting already-sorted data (1, 2, 3, 4, 5, in order) produces a tree where every node has only a right child — a chain of height n, which is a linked list in disguise, and search degrades to O(n) with no balance guarantee left. Self-balancing BST variants like AVL trees and Red-Black trees exist to fix exactly this, using rotations on every insert/delete to keep height at O(log n) regardless of insertion order — this lesson won't implement one, but it's worth knowing why they exist.

Connect it to a real scenario

If the Tutorial Platform keeps its lesson slugs in a sorted BST, it can search in O(log n) — slower than a dict hash lookup, but a BST can answer range queries ("all slugs between 'a' and 'm'") that a hash-based dict simply can't. The catch to watch for: bulk-importing a course's lessons in alphabetical order would produce a skewed tree and degrade search back to O(n).

Try the working example

python
class Node:
    def __init__(self, value, left=None, right=None):
        self.value = value
        self.left = left
        self.right = right

def insert(node, value):
    if node is None:
        return Node(value)
    if value < node.value:
        node.left = insert(node.left, value)
    else:
        node.right = insert(node.right, value)
    return node

def search(node, value):
    if node is None:
        return False
    if value == node.value:
        return True
    if value < node.value:
        return search(node.left, value)
    return search(node.right, value)

root = None
for slug in ["queues", "hash-tables", "stacks", "binary-trees", "linked-lists"]:
    root = insert(root, slug)

print(search(root, "stacks"))
print(search(root, "recursion"))
You should see
Prints True ("stacks" exists in the tree) followed by False ("recursion" was never inserted).

5-minute try-it

Modify the code to insert the slugs in already-sorted order (["binary-trees", "hash-tables", "linked-lists", "queues", "stacks"]) instead, then measure the resulting tree's height — what's different?

One important caution

Not reassigning insert's return value back onto the parent (calling insert(node.left, value) without node.left = ...) — the new node never actually gets linked into the tree

Assuming a BST always guarantees O(log n) — inserting sorted or nearly-sorted data can grow the height to n, degrading to O(n), a case that's easy to overlook

Wikipedia — Binary search treeData Structures & Algorithms

Easy traps

  • Not reassigning insert's return value back onto the parent (calling insert(node.left, value) without node.left = ...) — the new node never actually gets linked into the tree
  • Assuming a BST always guarantees O(log n) — inserting sorted or nearly-sorted data can grow the height to n, degrading to O(n), a case that's easy to overlook
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Modify the code to insert the slugs in already-sorted order (["binary-trees", "hash-tables", "linked-lists", "queues", "stacks"]) instead, then measure the resulting tree's height — what's different?

You'll know it worked when: Prints True ("stacks" exists in the tree) followed by False ("recursion" was never inserted).

Binary Search Trees — O(log n) Search | Thuta Learning