Python Tutorial

Binary Search Trees (BST)

An ordered binary tree that keeps values sorted, enabling O(log n) search, insert, and delete when balanced.

The BST Property

A binary search tree enforces one rule at every node: all values in the left subtree are smaller, all values in the right subtree are larger. This ordering lets you discard half the remaining tree at each step, just like binary search on a sorted array.

Insertion

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

def insert(root, value):
    if root is None:
        return Node(value)
    if value < root.value:
        root.left = insert(root.left, value)
    elif value > root.value:
        root.right = insert(root.right, value)
    return root                     # duplicates ignored

root = None
for v in [50, 30, 70, 20, 40, 60, 80]:
    root = insert(root, v)

Search

def search(root, value):
    if root is None or root.value == value:
        return root
    if value < root.value:
        return search(root.left, value)
    return search(root.right, value)

print(search(root, 60) is not None)   # True
print(search(root, 45) is not None)   # False

Each comparison halves the search space, so a balanced BST searches in O(log n).

In-Order Traversal Gives Sorted Order

def inorder(root, out):
    if root:
        inorder(root.left, out)
        out.append(root.value)
        inorder(root.right, out)
    return out

print(inorder(root, []))   # [20, 30, 40, 50, 60, 70, 80]

Deletion: Three Cases

Removing a node must preserve the BST property. Its in-order successor (smallest value in the right subtree) replaces a node with two children.

def min_node(node):
    while node.left:
        node = node.left
    return node

def delete(root, value):
    if root is None:
        return None
    if value < root.value:
        root.left = delete(root.left, value)
    elif value > root.value:
        root.right = delete(root.right, value)
    else:
        if root.left is None:       # 0 or 1 child
            return root.right
        if root.right is None:
            return root.left
        succ = min_node(root.right) # 2 children
        root.value = succ.value
        root.right = delete(root.right, succ.value)
    return root

root = delete(root, 30)

The Balance Problem

Inserting sorted data (1, 2, 3, 4, …) turns a BST into a straight line — height n, so operations degrade to O(n). Self-balancing variants fix this by restructuring after each change.

OperationBalancedDegenerate (sorted input)
Search / Insert / DeleteO(log n)O(n)

A plain BST guarantees ordering, not balance. For worst-case O(log n), use a self-balancing tree (AVL, Red-Black) — covered next.

Best Practices

  • Use a BST when you need sorted order plus fast search/insert/delete.
  • Shuffle or balance input to avoid degenerate chains.
  • In Python, sortedcontainers.SortedList gives BST-like performance without hand-coding one.
  • Remember the in-order = sorted property for range queries and k-th smallest.

Try It Yourself

Exercise 1: Insert 8, 3, 10, 1, 6 into a BST. What is the root's left child?

Show solution

3 — values smaller than the root (8) go left; 3 is the first such value and becomes the left child.

Exercise 2: What happens to a BST's performance if you insert already-sorted data?

Show solution

It degenerates into a linked list (height n), so operations become O(n). Use a self-balancing tree (AVL) to prevent this.

📘 Real-World Deep Dive

Knowing <strong>DSA Bst (algorithms & data structures)</strong> well is what turns algorithms & data structures from a curiosity into a daily tool — you'll reach for it in nearly every real project.

Real-Life Scenario

An end-to-end usage of DSA Bst that you'd actually see in a data pipeline or analytics notebook.

Real-Life Example

class BST:
    def __init__(self, val=None):
        self.val = val
        self.left = self.right = None

    def insert(self, x):
        if self.val is None:
            self.val = x; return
        cur = self
        while True:
            if x < cur.val:
                if cur.left is None: cur.left = BST(x); return
                cur = cur.left
            else:
                if cur.right is None: cur.right = BST(x); return
                cur = cur.right

b = BST()
for v in [7,3,9,1,5,8,10]:
    b.insert(v)
# (depth.manual print to keep example small)
print("root:", b.val, "left child:", b.left.val, "right child:", b.right.val)

Expected Output

(see source)

Common mistakes

  • Off-by-one errors in binary-search: the standard idiom is while lo <= hi with mid = (lo + hi) // 2.
  • Recursive algorithms blow the stack for n > ~10⁴; convert to iterative with an explicit stack.
  • Comparison algorithms (sorted(iterable)) are stable by default in Python — surprising for Java/C++ users.
  • Treating DSA Bst as a black box without reading the docs — the API has subtle defaults that bite when you scale.

🚀 Performance & Best Practices

  • Use bisect.bisect_left / bisect_right instead of writing your own binary search.
  • Convert a sorted search into a tuple-access pattern with numpy.searchsorted for huge arrays.
  • Use heapq for priority queues instead of maintaining a sorted list manually.
  • When working with algorithms & data structures, prefer vectorised / batched operations over Python loops.

🧪 Try It Yourself

  1. Reproduce the snippet on a representative slice of your own data.
  2. Profile the snippet with cProfile or timeit and find the single biggest improvement.
  3. Generalise the snippet into a small, reusable function you can drop into future projects.

FAQ: Binary Search Trees (BST)

Common questions about this page.

What is Binary Search Trees (BST)?

Binary Search Trees (BST) is a DSA lesson that explains binary search trees (bst) in Python. An ordered binary tree that keeps values sorted, enabling O(log n) search, insert, and delete when balanced. Copy the samples and run them in the Python... It is written for beginners who want a clear definition and working examples.

Should I run binary search trees (bst) examples locally for better learning?

Yes. Use the browser editor on StudyGrid for a quick check, then Download the example and run it on your computer. Local runs show real errors and the real toolchain, which is one of the fastest ways to learn binary search trees (bst) in this DSA Python lesson (Binary Search Trees (BST)).

How do I use binary search trees (bst) in Python?

To use binary search trees (bst) in Python, follow the examples on this StudyGrid page. Copy a snippet, run it in the browser, then Download and run it locally for better learning. Change the values and compare the output.

What is the syntax of binary search trees (bst)?

This Binary Search Trees (BST) tutorial shows binary search trees (bst) syntax with short Python examples. Use the code blocks in this lesson for the exact statements, then try them in your editor.

Binary Search Trees (BST) example for beginners

Yes. This page includes a beginner binary search trees (bst) example you can copy and run. It is designed for searches such as "binary search trees (bst) for beginners", "binary search trees (bst) example", and "how to use binary search trees (bst)".

What are common mistakes with binary search trees (bst)?

Common binary search trees (bst) mistakes include wrong syntax, mixing types, and skipping practice. Work through this DSA chapter in order, run every example, and check the output before moving on.

Why should I learn binary search trees (bst)?

Binary Search Trees (BST) is used in real Python work. Learning binary search trees (bst) helps you write clearer programs and continue the DSA tutorial on StudyGrid.

Is Binary Search Trees (BST) free to learn online?

Yes. You can learn binary search trees (bst) free on StudyGrid (studygrid.in). This chapter is part of the DSA path and includes examples, syntax, and next-step links.