computer-science/binary-search-trees-why-the-order-you-insert-numbers-changes-how-fast.md

Binary search trees: why the order you insert numbers changes how fast you can find them

Computer science · 4 min read ·

A *binary search tree* keeps numbers in order with one rule: smaller goes left, bigger goes right. Build one yourself, watch a search light up the path it takes, and see why the same seven numbers make a short tree or a long chain depending on the order you insert them.

You will run real Python for inserting, searching and measuring height, and learn why real databases use self-balancing trees to keep searches fast.

A binary search tree with seven numbers arranged in three levels, root 50

Suppose you keep a list of a million numbers and want to know whether 73,914 is in it. In an unsorted list you may have to check every number. If the list is sorted, binary search needs about 20 guesses. But a sorted list has a catch: adding a new number in the middle means shifting everything after it along by one place. Is there a way to keep data in order and add to it cheaply? There is, and it is called a binary search tree.

One rule, made of boxes

A node is a small box holding a value and two links, left and right, each pointing to another node or to nothing. A tree is nodes linked this way, starting from one node at the top called the root. A node with no children is a leaf.

The "binary search" part is a single rule, applied at every node: everything in the left branch is smaller than this node, and everything in the right branch is bigger. That is all. To find a value, start at the root and compare. Smaller? Go left. Bigger? Go right. Equal? Found it. Reach a link that points to nothing? It isn't there.

Build one and watch it search

Type a number and press Insert, or use the presets. Then type a number in the Find box: the nodes visited light up, and the count is the number of comparisons made.

Try "Mixed order" and find 80: three comparisons. Now press "Sorted order" and find 80 again: seven. Same numbers, same rule, very different shape. The shape depends on the order you inserted them in.

Why order changes the shape

The first number inserted becomes the root and never moves. Every later number walks down from the root using the same smaller-left, bigger-right rule and attaches itself at the first empty link it meets. If you insert 20, then 30, then 40, each one is bigger than everything before it, so each goes right, then right again. The tree becomes a chain, which is really a linked list in disguise, and searching it means checking one node at a time.

The height of a tree is the number of levels from the root down to the lowest leaf. A search never makes more comparisons than the height, so height is the number to watch.

The code

Each node is a tiny object, and the functions call themselves on a smaller branch (if recursion is new, see the recursion article):

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

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

def contains(node, value, steps=0):
    if node is None:
        return False, steps
    steps += 1
    if value == node.value:
        return True, steps
    if value < node.value:
        return contains(node.left, value, steps)
    return contains(node.right, value, steps)

def height(node):
    if node is None:
        return 0
    return 1 + max(height(node.left), height(node.right))

Building two trees from the same seven numbers and searching for 80 in each prints this (we ran it with Python 3):

mixed order  height: 3 find 80: (True, 3)
sorted order height: 7 find 80: (True, 7)

Duplicates are ignored here, because neither the < nor the > branch matches an equal value.

What this means at scale

A tree that stays reasonably balanced, with both sides about equally full, has a height of roughly log2 of the number of nodes. A million nodes fit in about 20 levels, so a search takes around 20 comparisons, the same as binary search. A tree that has collapsed into a chain over a million nodes needs up to a million comparisons.

That gap is why real systems don't use a plain tree on data that might arrive already sorted (timestamps and auto-incrementing ids often do). They use self-balancing trees, such as red-black trees or the B-trees many databases use for indexes. These rearrange nodes as you insert so the height stays near the minimum. You don't need to learn how they do it yet, only why they must: a tree is fast only while it stays short.

So the takeaway for your own code: a structure that keeps data in order can make both adding and searching quick, but only if its shape stays healthy. When a tool promises "fast lookups", it is worth asking what keeps it balanced.

$ ls computer-science/

see all →
computer-science/merge-sort-how-splitting-a-list-in-half-again-and-again-sorts-it-with.md Merge sort: how splitting a list in half again and again sorts it with far less work How do you sort 10,000 numbers without making millions of comparisons? Merge sort never sorts a big pile. It splits the list until every… 5 min read · 27 Oct computer-science/hash-tables-how-a-computer-finds-one-name-among-thousands-without-chec.md Hash tables: how a computer finds one name among thousands without checking them all Your phone finds one contact among thousands without reading them all. The trick is a hash table: a row of numbered slots and a small… 6 min read · 24 Oct computer-science/stacks-and-queues-why-undo-takes-the-newest-item-and-a-printer-takes-t.md Stacks and queues: why undo takes the newest item and a printer takes the oldest Press undo and the last thing you typed disappears first. Send documents to a shared printer and the first one is printed first. Both are… 5 min read · 20 Oct computer-science/breadth-first-search-how-a-maze-solver-finds-the-shortest-way-out.md Breadth-first search: how a maze solver finds the shortest way out How does a maze solver, or a map app, find the shortest route and not just any route? The answer is breadth-first search: explore every… 6 min read · 17 Oct computer-science/binary-search-how-to-find-one-number-in-a-million-with-20-guesses.md Binary search: how to find one number in a million with 20 guesses Guessing a number between 1 and 1,000,000 sounds like it could take a million tries. With binary search it takes at most 20. Step through a… 4 min read · 14 Oct computer-science/big-o-how-to-tell-if-your-code-will-survive-1-000-times-more-data.md Big O: how to tell if your code will survive 1,000 times more data Your code works on 10 items, then crawls on 10,000. Big O is the short way programmers describe how the number of steps grows as the input… 4 min read · 11 Oct