Skip to content

Binary Search Tree

A tree where every left child is smaller and every right child is larger, giving fast search, insert and delete when the tree stays balanced.

beginner20 minAsked oftenTreesSearchRecursion

Last reviewed 24 Oct 2026 · by TheLearningLoop Team

Read first: Data Structures & Algorithms: The Big Picture (blog post)

Progress is saved on this device. Create a free account to keep it everywhere.

On this page ▾

Key takeaways

  • Every left child is smaller and every right child is larger, at every node.
  • Search, insert and delete are O(log n) when the tree stays balanced, O(n) when it doesn't.
  • An in-order traversal visits every node in sorted order.

When to use a BST

Use a balanced BST when you need:

  • Keys kept in sorted order while data keeps changing, such as a live leaderboard.
  • Range queries: "all orders between two dates", "all scores from 1,000 to 2,000".
  • The nearest key: "the next job after now", "the closest price at or below 50".
  • A guaranteed worst case of O(log n), with no bad inputs.

Use something else when:

  • You only look up exact keys: use a hash map. It is faster and simpler.
  • You only ever need the smallest or largest item: use a heap.
  • The data never changes after loading: use a sorted array and binary search. It is smaller and faster in practice because it sits together in memory.
  • The data is far bigger than memory and lives on disk: use a B-tree, which is what databases do.

Do not write your own BST in production. Use your language's sorted map (see the real-world section), because it is already balanced and tested. Writing one by hand is for learning and interviews.

How a binary search tree works

A binary search tree (BST) is a binary tree with one rule that holds at every node:

Everything in the left subtree is smaller than the node, and everything in the right subtree is larger.

That rule turns every comparison into a decision that throws away half of what is left, just like binary search on a sorted array. The difference is that a BST also lets you insert and delete without shifting elements around.

Try it

Insert a few numbers, then search for one. Watch how each comparison picks a side and how the comparison counter grows with the height of the tree, not with the number of nodes.

Binary search tree

Step 15 of 17 · Press Space to play, arrow keys to step
Start from:
203040506070

Insert 80: compare with 50. 80 is larger, so go right.

comparisons:
1
height:
3
nodes:
6

Things to try:

  • Insert 50, 30, 70, 20, 40, 60, 80. The tree is perfectly balanced, and any search takes at most 3 comparisons.
  • Now insert 10, 20, 30, 40, 50, 60, 70 in that order. Every node goes right and the tree becomes a linked list. A search for 70 now takes 7 comparisons.

BST operations: search, insert and delete

Search. Start at the root. If the target is smaller, go left. If it is larger, go right. Stop when you find it, or when you reach an empty spot, which means the value isn't in the tree.

Insert. Search for the value. The empty spot where the search ends is exactly where the new node belongs.

Delete. There are three cases:

  1. Leaf: just remove it.
  2. One child: replace the node with its child.
  3. Two children: replace the node's value with its in-order successor, the smallest value in its right subtree. Then delete the successor's old node. It has at most one child, because a smallest value can't have a left child.

In-order traversal (left, node, right) visits values in sorted order. This is a favourite interview fact.

BST time complexity

OperationBalanced treeWorst case (skewed)
SearchO(log n)O(n)
InsertO(log n)O(n)
DeleteO(log n)O(n)
In-order traversalO(n)O(n)
SpaceO(n)O(n)

The worst case happens when values arrive already sorted. Self-balancing trees such as AVL and red-black trees fix this by rotating nodes (re-linking a few nodes so the tree gets shorter) after inserts and deletes so the height stays O(log n).

BST vs other data structures

The right choice depends on what you do most. Here is the same job done with each structure. n is the number of items.

What you needBalanced BSTHash mapSorted arrayHeapLinked list
Find one exact keyO(log n)O(1) averageO(log n)O(n)O(n)
Insert a new keyO(log n)O(1) averageO(n), shifts itemsO(log n)O(1) at the head
Delete a keyO(log n)O(1) averageO(n), shifts itemsO(log n)O(n) to find it
Walk keys in sorted orderO(n)O(n log n), sort firstO(n)O(n log n)O(n log n)
Range query ("between a and b")O(log n + k)O(n), scan allO(log n + k)O(n)O(n)
Nearest smaller or larger keyO(log n)O(n)O(log n)O(n)O(n)
Smallest or largest itemO(log n)O(n)O(1)O(1)O(n)

k is the number of results returned. The bold cells show where each structure wins. A balanced BST is rarely the fastest at any single job, but it is the only one that is good at all of the ordered jobs while still allowing cheap inserts.

How to explain a binary search tree in an interview

  • State the invariant first: "left is smaller, right is larger, at every node."
  • Say the complexity in terms of height h, then explain that h is log n when balanced and n when skewed.
  • Mention that a hash map gives O(1) average lookup but no ordering. Pick a BST when you need sorted iteration, range queries, or the nearest smaller or larger value.

Where you meet BSTs in real systems

You rarely write a raw BST at work, but balanced search trees are everywhere underneath the tools you use. Here are three of them drawn out, the first with code you can run, then more examples.

Example 1: Order books on a stock exchange

An order book keeps bids and asks sorted by price so it can always match the best price first. New orders arrive and old ones are cancelled all day, so the structure needs fast inserts and deletes while staying sorted. Many implementations use an ordered map keyed by price. Open the example below to see the picture and the code.

Code: an order book with best bid and best askTime O(log n)Memory O(n)
$100.90400 shares$100.70150 shares$100.60300 shares← best ask (lowest sell)spread: $0.10$100.50200 shares← best bid (highest buy)$100.40500 shares$100.30100 shares
Sellers (red) are sorted so the lowest price is at the bottom of their list. Buyers (green) are sorted so the highest price is at the top of theirs. The best bid and best ask are the two ends where the lists meet, which is exactly what an ordered tree finds in O(log n).
from sortedcontainers import SortedDict  # pip install sortedcontainers


class OrderBook:
    """Price levels for one stock. Prices are whole cents, e.g. 10_050 = $100.50.

    Memory: O(n) for n price levels. Each side is kept sorted by price.
    SortedDict is not a tree, but it gives the same ordered operations.
    """

    def __init__(self):
        self.bids = SortedDict()  # price -> quantity buyers want
        self.asks = SortedDict()  # price -> quantity sellers offer

    def set_level(self, side, price, quantity):
        """Add, change or remove one price level. Quantity 0 removes it.

        Time: O(log n) to find the spot, whether the level is new or not.
        """
        if quantity == 0:
            side.pop(price, None)
        else:
            side[price] = quantity

    def best_bid(self):
        """Highest price a buyer will pay, or None. Time: O(log n)."""
        return self.bids.peekitem(-1) if self.bids else None   # last = largest

    def best_ask(self):
        """Lowest price a seller will accept, or None. Time: O(log n)."""
        return self.asks.peekitem(0) if self.asks else None    # first = smallest

Each version keeps buy prices and sell prices in two sorted maps. Setting a level to quantity 0 cancels it. The best bid is the largest buy price and the best ask is the smallest sell price. Every version was compiled and run on the same six price levels and printed the same best bid and ask before and after cancelling the top bid. Go and Python need a package (github.com/google/btree and sortedcontainers) because neither has a sorted map built in.

Example 2: Database indexes

When you run SELECT * FROM orders WHERE created_at BETWEEN '2026-01-01' AND '2026-01-31', the database walks a B-tree index. A B-tree is like a BST where each node holds many keys and has many children. One node fills one disk page, so the database reads fewer pages per lookup. The ordering is what makes the range query fast: find the start, then read forward.

root: 01-20 | 02-012026-01-02 01-09 01-1501-21 01-28 01-3102-03 02-10 02-18page 1: readpage 2: readstop: past 31 Jan
The database goes down once to find 1 January, then reads the leaf pages in order until it passes 31 January. Only 3 pages are touched.

Example 3: The Linux CPU scheduler

Linux's Completely Fair Scheduler (CFS) kept runnable tasks in a red-black tree keyed by how much CPU time each had used. Picking the next task meant taking the leftmost node, the one that had run the least. Since Linux 6.6 the scheduler uses a newer algorithm called EEVDF, which also keeps its tasks in a balanced tree.

40 ms25 ms60 ms10 ms30 msruns next ↑
Each node is a task, keyed by how much CPU time it has used. The leftmost node has used the least, so it runs next. After it runs, it is re-inserted with a larger key.

More real-world scenarios

4. Leaderboards and "rank between" queries

A game that needs "everyone with a score between 1,000 and 2,000" or "the three players just above me" needs ordered data that changes with every match. A hash map cannot answer these without scanning every player.

5. Java's HashMap, quietly

When many keys land in the same bucket of a Java HashMap, a bucket that grows past 8 entries is turned into a red-black tree. Lookups in that bucket then cost O(log n) instead of O(n), which protects the map from slow or malicious inputs.

6. File systems

Modern file systems such as Btrfs, XFS and NTFS keep directory entries and file extents in B-tree variants. Looking up one file name in a folder with a million files stays fast, and listing a folder comes out in sorted order.

7. Calendar and booking conflicts

"Is this meeting slot free?" means finding the nearest existing booking before and after the new start time. An ordered tree answers that in O(log n). A variation called an interval tree handles overlapping time ranges, as used by meeting-room and hotel booking systems.

8. Timers and scheduled jobs

A timer system needs "which job is due next, and what is due before now?" Keeping jobs in a tree ordered by due time gives you both answers, and cancelling a job is a normal delete. Some runtimes use heaps or timer wheels instead, which is a good example of picking by access pattern.

9. Memory management

Operating systems track which ranges of a program's memory are in use. Linux kept these ranges in a red-black tree so it could find "the range that contains this address" quickly. Newer kernels use a related structure called a maple tree for the same job.

10. Autocomplete and "nearest value" lookups

Pricing tables, tax brackets, shipping tiers and rate cards are all "find the largest threshold at or below this value". A sorted map's floor operation does that in one call, for example floorEntry in Java or lower_bound in C++.

Language standard libraries

Most languages already ship a sorted map or set. Check how yours works before writing your own.

LanguageSorted map or setWhat it is under the hoodNotes
JavaTreeMap, TreeSetRed-black treeHas floorKey, ceilingKey and subMap for range queries.
C++std::map, std::setUsually a red-black treelower_bound and upper_bound for nearest-key and range queries.
C#SortedDictionary, SortedSetRed-black treeSortedSet has GetViewBetween for ranges.
RustBTreeMap, BTreeSetB-tree, not a binary treeUse range(a..b) for range queries. Rust's HashMap is unordered.
PythonNone built inThird-party sortedcontainers (SortedDict, SortedList)Not a tree, but gives the same ordered operations. For plain sorted lists, use the built-in bisect module.
GoNone built inThird-party packages, such as github.com/google/btreeGo's built-in map is a hash map with no ordering.
JavaScriptNone built inThird-party packagesMap keeps insertion order, not sorted order.
KotlinTreeMap, sortedMapOfRed-black tree (uses Java's)Same operations as Java.

The takeaway from the table: the languages that ship an ordered structure use a balanced tree for it. The ones that don't expect you to pull in a package, or to keep a sorted array and use binary search.

The takeaway

Whenever a system needs ordered data plus fast inserts, look for a balanced search tree. When it only needs exact-match lookups, it usually uses a hash map instead.

Interview questions

Try answering out loud before you reveal hints. Interviewers care about how you reason, not just the final answer.

  1. 1.

    Given the root of a binary tree, check whether it is a valid binary search tree.

    medium
  2. 2.

    Find the k-th smallest element in a BST.

    medium
  3. 3.

    Delete a node with a given key from a BST and return the new root.

    medium
  4. 4.

    When would you choose a balanced BST over a hash map?

    easy
  5. 5.

    Find the lowest common ancestor of two nodes in a BST.

    medium

↑ Back to top

Next lesson