Skip to main content

๐ŸŒณ Trees

One-line summary: Hierarchical node structures โ€” master traversals (inorder, BFS, DFS), BST properties, and path problems for O(n) or O(log n) solutions.


Visual Learningโ€‹

Enhanced Tree Traversal Animationโ€‹

Enhanced Tree Traversal Animation Interactive visualization of all tree traversal methods with smooth animations, node state changes, and real-time sequence display

Tree Operations Complexity Chartโ€‹

Complexity Analysis Visual comparison of time complexities for different tree operations


Core Conceptsโ€‹

What are Trees?โ€‹

A tree is a hierarchical data structure consisting of nodes connected by edges. Unlike linear structures (arrays, linked lists), trees branch outward, making them ideal for representing nested or parent-child relationships.

Formally, a tree can be defined recursively: a node (the root) containing a value and a list of references to child nodes, with exactly one path between any two nodes and no cycles.

Key Terminologyโ€‹

TermDefinition
RootThe topmost node with no parent
LeafA node with no children
EdgeThe link between a parent and child node
HeightLength of the longest path from node to a leaf (edges)
DepthLength of the path from root to node (edges)
SubtreeAny node and all its descendants, itself a valid tree
SiblingNodes sharing the same parent
AncestorAny node on the path from root to a given node (including the root)
DescendantAny node reachable by repeatedly following child pointers

Types of Treesโ€‹

  • Binary Tree: Each node has at most 2 children (left and right)
  • Binary Search Tree (BST): Binary tree where left subtree values < node value < right subtree values
  • Balanced Tree: Height difference between left and right subtrees is at most 1 (e.g., AVL, Red-Black)
  • Complete Binary Tree: All levels filled except possibly the last, filled left to right
  • Full Binary Tree: Every node has either 0 or 2 children
  • Perfect Binary Tree: All internal nodes have 2 children, all leaves at same level
  • N-ary Tree: Each node can have up to N children (e.g., Trie, file system)

Real-World Use Casesโ€‹

  • File systems โ€” directories contain files and subdirectories (N-ary tree)
  • HTML DOM โ€” nested element hierarchy
  • Database indexes โ€” B-Trees and B+ Trees for efficient lookups
  • Expression parsing โ€” abstract syntax trees (ASTs) in compilers
  • Routing โ€” network routing tables use tree structures
  • AI/ML โ€” decision trees, random forests
  • Compression โ€” Huffman coding trees
  • Version control โ€” Git's commit DAG (directed acyclic graph, a tree variant)

When NOT to Use Treesโ€‹

  • Simple linear access patterns (use arrays or linked lists)
  • Constant-time random access required (use hash tables)
  • Memory-constrained environments with high pointer overhead
  • Data has no hierarchical relationship

Essential Tree Traversalsโ€‹

Depth-First Search (DFS)โ€‹

  • Inorder (L-N-R): Left โ†’ Node โ†’ Right

    • Sequence: 8 โ†’ 4 โ†’ 2 โ†’ 9 โ†’ 5 โ†’ 1 โ†’ 6 โ†’ 3 โ†’ 7
    • Use Case: Yields sorted order for BST, expression evaluation
  • Preorder (N-L-R): Node โ†’ Left โ†’ Right

    • Sequence: 1 โ†’ 2 โ†’ 4 โ†’ 8 โ†’ 5 โ†’ 9 โ†’ 3 โ†’ 6 โ†’ 7
    • Use Case: Tree serialization/copying, prefix expressions
  • Postorder (L-R-N): Left โ†’ Right โ†’ Node

    • Sequence: 8 โ†’ 4 โ†’ 9 โ†’ 5 โ†’ 2 โ†’ 6 โ†’ 7 โ†’ 3 โ†’ 1
    • Use Case: Tree deletion, computing directory sizes, postfix expressions

Breadth-First Search (BFS)โ€‹

  • Level-order: Visit nodes level by level, left to right
    • Sequence: 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ 6 โ†’ 7 โ†’ 8 โ†’ 9
    • Use Case: Shortest path in unweighted trees, level-wise aggregation, tree printing

Complexity Analysisโ€‹

BST Operationsโ€‹

OperationAverageWorstSpaceNotes
SearchO(log n)O(n)O(h)Degenerates to O(n) if tree becomes a chain
InsertO(log n)O(n)O(h)Must maintain BST property after insertion
DeleteO(log n)O(n)O(h)Three cases: leaf, one child, or two children

h = height of tree (log n for balanced, n for skewed)

Tree Traversal Complexitiesโ€‹

TraversalTimeSpaceNotes
Inorder (DFS)O(n)O(h)Stack depth for recursion
Preorder (DFS)O(n)O(h)Same as above
Postorder (DFS)O(n)O(h)Same as above
Level-order (BFS)O(n)O(w)Queue stores at most the widest level

w = maximum width of tree (up to n/2 for a complete binary tree, so O(n) worst case)


Common Patternsโ€‹

Inorder DFS (Recursive)โ€‹

function inorder(root, result = []) {
if (!root) return result;
inorder(root.left, result);
result.push(root.val);
inorder(root.right, result);
return result;
}

Level Order BFS (Iterative)โ€‹

function levelOrder(root) {
if (!root) return [];
const queue = [root],
result = [];
while (queue.length) {
const size = queue.length,
level = [];
for (let i = 0; i < size; i++) {
const n = queue.shift();
level.push(n.val);
if (n.left) queue.push(n.left);
if (n.right) queue.push(n.right);
}
result.push(level);
}
return result;
}

Lowest Common Ancestor (LCA)โ€‹

function lowestCommonAncestor(root, p, q) {
if (!root || root === p || root === q) return root;
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
return left && right ? root : left || right;
}

Iterative DFS (Stack-Based)โ€‹

function dfsIterative(root) {
if (!root) return [];
const stack = [root],
result = [];
while (stack.length) {
const node = stack.pop();
result.push(node.val);
if (node.right) stack.push(node.right);
if (node.left) stack.push(node.left);
}
return result;
}

BST Validationโ€‹

function isValidBST(root, min = -Infinity, max = Infinity) {
if (!root) return true;
if (root.val <= min || root.val >= max) return false;
return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
}

Tree Height (Bottom-Up)โ€‹

function maxDepth(root) {
if (!root) return 0;
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}

Pitfalls & Edge Casesโ€‹

  • Always null-check before accessing .left or .right โ€” root or any child can be null
  • BST validation requires min/max bounds, not just comparing node with its direct parent
  • Height vs depth confusion: height = edges from node โ†’ deepest leaf; depth = edges from root โ†’ node
  • Recursion depth limits: A skewed tree of 10โต nodes will overflow the call stack โ€” use iterative approaches for deep trees
  • BFS queue size: For a complete tree, the queue can hold n/2 nodes at the widest level
  • Duplicate values in BST: Typically duplicates go to the left or are disallowed entirely โ€” clarify with your interviewer
  • Inorder successor for delete: When deleting a node with two children, replace it with the inorder successor (smallest in right subtree) or predecessor (largest in left subtree)
  • Empty tree: Many tree functions need to handle root === null gracefully

Implementation Referenceโ€‹

Runnable implementations (with tests) live alongside this guide in this folder:

Also see the Interview Guide for curated practice sets.


  • Recursion โ€” most tree algorithms are naturally recursive
  • Heap โ€” a heap is a complete binary tree with ordering constraints
  • Queue โ€” BFS traversal depends on a queue data structure
  • Stack โ€” DFS traversal uses a stack (or recursion call stack)
  • Trie โ€” an N-ary tree specialized for string prefix operations

Referencesโ€‹

โ† Back to DSA ยท ยฉ sparshjaswal