Skip to content

Trees

Hierarchical data structures for efficient operations


Overview

A tree is a hierarchical, non-linear data structure consisting of nodes connected by edges. Trees are used to represent hierarchical relationships and enable efficient searching, insertion, and deletion operations. They form the foundation for many advanced data structures and algorithms commonly tested in technical interviews.

What is a Tree?

A tree consists of:

  • Root: The topmost node with no parent
  • Nodes: Elements containing data and references to child nodes
  • Edges: Connections between parent and child nodes
  • Leaves: Nodes with no children

A Binary Tree is a tree where each node has at most two children (left and right). A Binary Search Tree (BST) is a binary tree with the ordering property: left subtree values < node value < right subtree values.

When to Use Trees

Use CaseWhy Trees Work Well
Hierarchical dataFile systems, organization charts, HTML DOM
Fast search/insert/deleteBST provides O(log n) average case
Sorted data traversalInorder traversal of BST gives sorted order
Priority operationsHeaps (special trees) for min/max extraction
Prefix matchingTries for autocomplete, spell checkers
Expression evaluationParse trees for mathematical expressions

When to Consider Alternatives

ScenarioBetter Alternative
Simple linear sequenceArray or Linked List
Key-value lookups onlyHash Table (O(1) average)
Need bidirectional traversalDoubly Linked List
Graph with cyclesGeneral Graph

Document Structure

ProblemDifficultyTechniqueLink
Maximum Depth of Binary TreeEasyDFS RecursionLink
Balanced Binary TreeEasyDFS + HeightLink
Same TreeEasyDFS ComparisonLink
Symmetric TreeEasyDFS/BFS MirrorLink
Invert Binary TreeEasyDFS/BFSLink
Subtree of Another TreeEasyDFS + Same TreeLink
Diameter of Binary TreeEasyDFS + Global MaxLink
Validate BSTMediumInorder/Range CheckLink
Lowest Common Ancestor (BST)MediumBST PropertyLink
Lowest Common Ancestor (Binary Tree)MediumDFS RecursionLink
Path Sum I, II, IIIEasy-MediumDFS BacktrackingLink
Binary Tree Level Order TraversalMediumBFS QueueLink
Zigzag Level Order TraversalMediumBFS + DirectionLink
Binary Tree Right Side ViewMediumBFS/DFSLink
Kth Smallest Element in BSTMediumInorder TraversalLink
BST IteratorMediumInorder StackLink
Construct Binary Tree from TraversalsMediumRecursion + IndexLink
Serialize/Deserialize Binary TreeHardDFS/BFS + FormatLink
Binary Tree Maximum Path SumHardDFS + Global MaxLink
Count Good Nodes in Binary TreeMediumDFS + Max TrackingLink
Boundary of Binary TreeMediumDFS Left-Leaves-RightLink

Tree Terminology

Basic Terms

TermDefinition
RootThe topmost node (no parent)
NodeAn element containing data and child references
LeafA node with no children (terminal node)
EdgeConnection between parent and child
ParentNode directly above another node
ChildNode directly below another node
SiblingNodes sharing the same parent
AncestorAny node on the path from root to a node
DescendantAny node reachable from a given node

Height vs Depth

        1        <- Depth 0, Height 2
       / \
      2   3      <- Depth 1, Height 1
     / \
    4   5        <- Depth 2, Height 0 (leaves)
MeasureDefinitionCalculation
DepthDistance from root to nodeCount edges from root down
HeightDistance from node to deepest leafCount edges to furthest leaf
Tree HeightHeight of root nodeMaximum depth of any leaf

Binary Tree Types

TypeDefinitionProperties
Full Binary TreeEvery node has 0 or 2 childrenNo single-child nodes
Complete Binary TreeAll levels filled except possibly last; last level filled left-to-rightUsed in heaps
Perfect Binary TreeAll internal nodes have 2 children, all leaves at same level2^h - 1 nodes at height h
Balanced Binary TreeHeight of left and right subtrees differ by at most 1O(log n) operations
Degenerate/SkewedEach parent has only one childEssentially a linked list
Full:          Complete:       Perfect:        Skewed:
    1              1              1              1
   / \           / | \          / \              \
  2   3         2  3  4        2   3              2
 / \           /               / \ / \             \
4   5         5               4  5 6  7             3

BST Property

For every node in a Binary Search Tree:

  • All values in the left subtree are less than the node's value
  • All values in the right subtree are greater than the node's value
       8
      / \
     3   10
    / \    \
   1   6    14
      / \   /
     4   7 13

Inorder traversal gives sorted order: 1, 3, 4, 6, 7, 8, 10, 13, 14

Tree Traversals

Mermaid Diagram

Traversal Orders

TraversalOrderResultUse Case
PreorderRoot-Left-Right1,2,4,5,3,6,7Copy tree, serialize, prefix expression
InorderLeft-Root-Right4,2,5,1,6,3,7BST sorted order, infix expression
PostorderLeft-Right-Root4,5,2,6,7,3,1Delete tree, evaluate postfix, calc size
Level-orderBFS by level1,2,3,4,5,6,7Level-by-level processing, shortest path

DFS vs BFS Summary

AspectDFS (Depth-First)BFS (Breadth-First)
Data StructureStack / RecursionQueue
MemoryO(h) - height of treeO(w) - max width
OrderGoes deep before wideGoes level by level
Use CasePath finding, backtrackingShortest path, level order
ImplementationOften recursiveIterative with queue

Tree Traversal Templates

DFS Recursive

python
def preorder(root):
    """Root -> Left -> Right"""
    if not root:
        return []
    return [root.val] + preorder(root.left) + preorder(root.right)

def inorder(root):
    """Left -> Root -> Right (gives sorted order for BST)"""
    if not root:
        return []
    return inorder(root.left) + [root.val] + inorder(root.right)

def postorder(root):
    """Left -> Right -> Root"""
    if not root:
        return []
    return postorder(root.left) + postorder(root.right) + [root.val]

DFS Iterative (Using Stack)

python
def preorder_iterative(root):
    """Preorder using explicit stack"""
    if not root:
        return []

    result = []
    stack = [root]

    while stack:
        node = stack.pop()
        result.append(node.val)
        # Push right first so left is processed first
        if node.right:
            stack.append(node.right)
        if node.left:
            stack.append(node.left)

    return result

def inorder_iterative(root):
    """Inorder using explicit stack"""
    result = []
    stack = []
    curr = root

    while curr or stack:
        # Go to leftmost node
        while curr:
            stack.append(curr)
            curr = curr.left

        curr = stack.pop()
        result.append(curr.val)
        curr = curr.right

    return result

def postorder_iterative(root):
    """Postorder: modified preorder then reverse"""
    if not root:
        return []

    result = []
    stack = [root]

    while stack:
        node = stack.pop()
        result.append(node.val)
        # Push left first (opposite of preorder)
        if node.left:
            stack.append(node.left)
        if node.right:
            stack.append(node.right)

    return result[::-1]  # Reverse to get postorder

BFS Level Order

python
from collections import deque

def level_order(root):
    """BFS level-by-level traversal"""
    if not root:
        return []

    result = []
    queue = deque([root])

    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)

    return result

Common Tree Patterns

Pattern 1: Calculate Tree Property (Height, Balanced, Diameter)

python
def max_depth(root):
    """Maximum depth of binary tree"""
    if not root:
        return 0
    return 1 + max(max_depth(root.left), max_depth(root.right))

def is_balanced(root):
    """Check if tree is height-balanced"""
    def check(node):
        if not node:
            return 0

        left = check(node.left)
        right = check(node.right)

        if left == -1 or right == -1 or abs(left - right) > 1:
            return -1

        return 1 + max(left, right)

    return check(root) != -1

def diameter(root):
    """Diameter: longest path between any two nodes"""
    max_diameter = [0]

    def height(node):
        if not node:
            return 0

        left = height(node.left)
        right = height(node.right)

        # Update diameter (path through this node)
        max_diameter[0] = max(max_diameter[0], left + right)

        return 1 + max(left, right)

    height(root)
    return max_diameter[0]

Pattern 2: BST Validation and Operations

python
def is_valid_bst(root, min_val=float('-inf'), max_val=float('inf')):
    """Validate BST using range checking"""
    if not root:
        return True

    if root.val <= min_val or root.val >= max_val:
        return False

    return (is_valid_bst(root.left, min_val, root.val) and
            is_valid_bst(root.right, root.val, max_val))

def kth_smallest(root, k):
    """Find kth smallest element in BST using inorder"""
    stack = []
    curr = root

    while curr or stack:
        while curr:
            stack.append(curr)
            curr = curr.left

        curr = stack.pop()
        k -= 1
        if k == 0:
            return curr.val
        curr = curr.right

    return -1

Pattern 3: Lowest Common Ancestor (LCA)

python
def lca_bst(root, p, q):
    """LCA in BST - use BST property"""
    while root:
        if p.val < root.val and q.val < root.val:
            root = root.left
        elif p.val > root.val and q.val > root.val:
            root = root.right
        else:
            return root
    return None

def lca_binary_tree(root, p, q):
    """LCA in general binary tree"""
    if not root or root == p or root == q:
        return root

    left = lca_binary_tree(root.left, p, q)
    right = lca_binary_tree(root.right, p, q)

    if left and right:
        return root  # p and q are in different subtrees

    return left or right

Pattern 4: Path Sum Problems

python
def has_path_sum(root, target_sum):
    """Check if root-to-leaf path equals target sum"""
    if not root:
        return False

    if not root.left and not root.right:
        return root.val == target_sum

    remaining = target_sum - root.val
    return (has_path_sum(root.left, remaining) or
            has_path_sum(root.right, remaining))

def path_sum_ii(root, target_sum):
    """Find all root-to-leaf paths with target sum"""
    result = []

    def dfs(node, path, remaining):
        if not node:
            return

        path.append(node.val)

        if not node.left and not node.right and remaining == node.val:
            result.append(path[:])  # Copy path

        dfs(node.left, path, remaining - node.val)
        dfs(node.right, path, remaining - node.val)

        path.pop()  # Backtrack

    dfs(root, [], target_sum)
    return result

Pattern 5: Tree Construction

python
def build_tree(preorder, inorder):
    """Build tree from preorder and inorder traversals"""
    if not preorder or not inorder:
        return None

    root = TreeNode(preorder[0])
    mid = inorder.index(preorder[0])

    root.left = build_tree(preorder[1:mid+1], inorder[:mid])
    root.right = build_tree(preorder[mid+1:], inorder[mid+1:])

    return root

Complexity Analysis

Time Complexity

OperationBST (Average)BST (Worst)Balanced BST
SearchO(log n)O(n)O(log n)
InsertO(log n)O(n)O(log n)
DeleteO(log n)O(n)O(log n)
TraversalO(n)O(n)O(n)

Space Complexity

TraversalRecursiveIterative
DFSO(h) call stackO(h) explicit stack
BFSN/AO(w) queue width
  • h = height of tree (log n for balanced, n for skewed)
  • w = maximum width of tree (up to n/2 for complete tree)

Interview Focus

Based on recent SDE interview patterns, these tree topics are most frequently tested:

High Priority Topics

  1. Tree Traversals - Master all four traversals (preorder, inorder, postorder, level-order) both recursively and iteratively
  2. BST Operations - Validate BST, search, insert, delete, find kth smallest/largest
  3. Lowest Common Ancestor - Both BST and general binary tree variants
  4. Tree Properties - Height, depth, diameter, balanced check
  5. Path Problems - Path sum, maximum path sum, all paths with target

Common Google Tree Questions

Question TypeExample ProblemKey Insight
TraversalZigzag Level OrderBFS with direction alternation
ValidationValidate BSTRange checking or inorder sequence
LCALowest Common AncestorBST property vs general recursion
Path SumBinary Tree Maximum Path SumDFS with global max tracking
ConstructionBuild Tree from TraversalsPreorder gives root, inorder gives split
SerializationSerialize/Deserialize TreePreorder with null markers

What Interviewers Look For

  1. Clarifying Questions

    • Is it a BST or general binary tree?
    • Can there be duplicate values?
    • What should be returned (boolean, node, value)?
    • What about empty trees or single nodes?
  2. Problem-Solving Approach

    • Identify traversal type needed (DFS vs BFS)
    • Consider recursive vs iterative solution
    • Think about what information to pass down/up
    • Handle base cases carefully
  3. Code Quality

    • Clean recursive structure
    • Proper null checks
    • Meaningful variable names
    • Handle edge cases (empty tree, single node, skewed tree)
  4. Complexity Analysis

    • Time: Usually O(n) for traversal-based solutions
    • Space: Consider recursion stack depth O(h)

Common Mistakes to Avoid

  1. Forgetting base cases - Always check for null root first
  2. Not handling single-child nodes - Important for path problems
  3. Confusing BST vs Binary Tree - BST has ordering property
  4. Stack overflow on large trees - Consider iterative for skewed trees
  5. Not preserving BST property - After modifications, tree may become invalid

Practice Progression

Week 1: Foundations

DayFocusProblems
1TraversalsBinary Tree Inorder, Preorder, Postorder Traversal
2Tree PropertiesMaximum Depth, Balanced Tree, Diameter
3Basic BSTSearch in BST, Validate BST, Invert Tree

Week 2: Intermediate

DayFocusProblems
4Level OrderLevel Order Traversal, Zigzag, Right Side View
5LCA & AncestorsLCA of BST, LCA of Binary Tree, Kth Smallest
6Path ProblemsPath Sum I, II, III

Week 3: Advanced

DayFocusProblems
7ConstructionBuild Tree from Preorder/Inorder, Serialize Tree
8Advanced PathsMaximum Path Sum, Longest Univalue Path
9Mixed PracticeRandom selection from all patterns

Quick Reference Card

Time Complexity Cheat Sheet

Traversals:     O(n)     - Visit each node once
BST Search:     O(log n) - Balanced, O(n) worst case
BST Insert:     O(log n) - Balanced, O(n) worst case
Height/Depth:   O(n)     - Must visit all nodes
LCA:            O(n)     - Binary Tree, O(log n) BST

Pattern Recognition Triggers

If you see...Think about...
"Binary Search Tree"Use BST property (left < root < right)
"Level by level"BFS with queue
"Root to leaf path"DFS with backtracking
"Lowest common ancestor"BST property or recursive search
"Maximum/Minimum path"DFS with global variable
"Serialize/Deserialize"Preorder with null markers
"Validate tree"Range checking or inorder sequence
"Kth smallest/largest"Inorder traversal with counter

Resources

Further Reading


Last updated: January 2026

Trees are where interview difficulty ramps up. Unlike arrays or linked lists, trees require you to think recursively, interpret hierarchical relationships, and reason about traversal order. Master the traversal templates and common patterns - they form the foundation for solving the majority of tree problems in technical interviews.