BST - (Theory)


Binary Search Tree (BST)

Definition

A Binary Search Tree (BST) is a binary tree in which every node follows the property:

left subtree < node < right subtree

This must be true recursively for all nodes.


Properties of BST

Property Description
Ordering In-order traversal gives sorted order.
No duplicates Typically, BSTs do not store duplicate values.
Search time (average) O(log n) for balanced BST
Search time (worst case) O(n) for skewed BST
Space complexity O(n)
Min/Max element Leftmost/rightmost leaf node

Node Structure in Java

class TreeNode {
    int val;
    TreeNode left, right;

    TreeNode(int val) {
        this.val = val;
    }
}

Core BST Operations (Java)

1. Insertion

public TreeNode insert(TreeNode root, int key) {
    if (root == null) return new TreeNode(key);
    if (key < root.val) root.left = insert(root.left, key);
    else if (key > root.val) root.right = insert(root.right, key);
    return root;
}
public boolean search(TreeNode root, int key) {
    if (root == null) return false;
    if (key == root.val) return true;
    else if (key < root.val) return search(root.left, key);
    else return search(root.right, key);
}

3. Deletion

public TreeNode delete(TreeNode root, int key) {
    if (root == null) return null;

    if (key < root.val) root.left = delete(root.left, key);
    else if (key > root.val) root.right = delete(root.right, key);
    else {
        if (root.left == null) return root.right;
        if (root.right == null) return root.left;
        TreeNode minNode = getMin(root.right);
        root.val = minNode.val;
        root.right = delete(root.right, minNode.val);
    }
    return root;
}

private TreeNode getMin(TreeNode node) {
    while (node.left != null) node = node.left;
    return node;
}

Traversals (DFS)

Inorder (Left → Root → Right)

public void inorder(TreeNode root) {
    if (root != null) {
        inorder(root.left);
        System.out.print(root.val + " ");
        inorder(root.right);
    }
}

Preorder and Postorder also follow standard recursion.


Time and Space Complexity

Operation Avg-case Worst-case
Search O(log n) O(n)
Insert O(log n) O(n)
Delete O(log n) O(n)

Worst-case occurs when the tree becomes skewed (like a linked list).


AVL Tree (Adelson-Velsky and Landis Tree)

Definition

AVL Tree is a self-balancing BST where for every node:

|height(left) - height(right)| <= 1

Properties of AVL Tree

Property Value
Balance Factor (BF) -1, 0, +1
Time Complexity O(log n)
Guarantees balance Yes
Search, Insert, Delete O(log n)

Balance Factor

balanceFactor = height(left subtree) - height(right subtree)

Rotations (for balancing)

1. Right Rotation (LL Case)

private TreeNode rightRotate(TreeNode y) {
    TreeNode x = y.left;
    TreeNode T2 = x.right;

    x.right = y;
    y.left = T2;

    y.height = Math.max(height(y.left), height(y.right)) + 1;
    x.height = Math.max(height(x.left), height(x.right)) + 1;

    return x;
}

2. Left Rotation (RR Case)

private TreeNode leftRotate(TreeNode x) {
    TreeNode y = x.right;
    TreeNode T2 = y.left;

    y.left = x;
    x.right = T2;

    x.height = Math.max(height(x.left), height(x.right)) + 1;
    y.height = Math.max(height(y.left), height(y.right)) + 1;

    return y;
}

3. Left-Right Rotation (LR Case)

// Step 1: Left Rotate
root.left = leftRotate(root.left);
// Step 2: Right Rotate
return rightRotate(root);

4. Right-Left Rotation (RL Case)

// Step 1: Right Rotate
root.right = rightRotate(root.right);
// Step 2: Left Rotate
return leftRotate(root);

AVL Insertion (Java Full Logic)

class AVLNode {
    int val, height;
    AVLNode left, right;

    AVLNode(int val) {
        this.val = val;
        this.height = 1;
    }
}

class AVLTree {
    private int height(AVLNode node) {
        return node == null ? 0 : node.height;
    }

    private int getBalance(AVLNode node) {
        return node == null ? 0 : height(node.left) - height(node.right);
    }

    private AVLNode rightRotate(AVLNode y) {
        AVLNode x = y.left;
        AVLNode T2 = x.right;
        x.right = y;
        y.left = T2;
        y.height = Math.max(height(y.left), height(y.right)) + 1;
        x.height = Math.max(height(x.left), height(x.right)) + 1;
        return x;
    }

    private AVLNode leftRotate(AVLNode x) {
        AVLNode y = x.right;
        AVLNode T2 = y.left;
        y.left = x;
        x.right = T2;
        x.height = Math.max(height(x.left), height(x.right)) + 1;
        y.height = Math.max(height(y.left), height(y.right)) + 1;
        return y;
    }

    public AVLNode insert(AVLNode node, int key) {
        if (node == null) return new AVLNode(key);
        if (key < node.val) node.left = insert(node.left, key);
        else if (key > node.val) node.right = insert(node.right, key);
        else return node;

        node.height = 1 + Math.max(height(node.left), height(node.right));
        int balance = getBalance(node);

        // LL
        if (balance > 1 && key < node.left.val) return rightRotate(node);
        // RR
        if (balance < -1 && key > node.right.val) return leftRotate(node);
        // LR
        if (balance > 1 && key > node.left.val) {
            node.left = leftRotate(node.left);
            return rightRotate(node);
        }
        // RL
        if (balance < -1 && key < node.right.val) {
            node.right = rightRotate(node.right);
            return leftRotate(node);
        }

        return node;
    }
}

AVL Tree Time Complexity

Operation Time
Insert O(log n)
Delete O(log n)
Search O(log n)

Summary

Feature BST AVL Tree
Balanced Not always Always
Time Complexity O(log n) - O(n) Always O(log n)
Best for Simple use cases Time-sensitive ops
Rotations No Yes (4 types)