Trees in Data Structures
The Complete Visual Guide
What is a Tree?
Unlike Arrays, Linked Lists, Stacks, and Queues which are linear data structures, a Tree is a hierarchical, non-linear data structure consisting of nodes connected by edges. It represents hierarchical relationships, starting from a single root node and expanding downwards into branches and leaves.
Why Trees? (Advantages)
- Hierarchical Modeling: Naturally represents real-world hierarchies (File systems, DOM).
- Efficient Searching: Trees (like BST) offer $O(\log n)$ search time, significantly faster than $O(n)$ in arrays/linked lists.
- Dynamic Size: Like linked lists, trees grow and shrink dynamically without memory reallocation overhead.
- Fast Insertion/Deletion: Self-balancing trees guarantee $O(\log n)$ operations.
Real-World Applications
Essential Terminology
Root
The topmost node of the tree. It has no parent.
Parent
A node that has one or more child nodes connected below it.
Child
A node directly connected to another node (parent) above it.
Leaf (External Node)
A node with zero children. The terminal points of the tree.
Internal Node
Any node that has at least one child (not a leaf).
Sibling
Nodes that share the exact same parent.
Ancestor
Any predecessor node on the path from the root to that node.
Descendant
Any successor node on the path from the node to a leaf.
Degree
The total number of children a specific node has.
Level
The number of edges along the path from the root to the node. Root is Level 0.
Depth
The length of the path from the root to the node.
Height
The length of the longest path from the node to a leaf. Height of tree = height of root.
Tree Shapes
Complete Tree
All levels are fully filled except possibly the last, which is filled left-to-right.
Full (Strict) Tree
Every node has exactly 0 or 2 children.
Perfect Tree
All internal nodes have 2 children and all leaves are at the same level.
Balanced Tree
Height of left and right subtrees of every node differ by at most 1.
Degenerate Tree
Every internal node has exactly one child. Behaves like a linked list.
Tree Traversals
Traversal is the process of visiting every node in the tree exactly once. Unlike linear data structures, trees can be traversed in multiple ways.
- 1. Preorder (Root, Left, Right):
1 → 2 → 4 → 5 → 3 → 6 → 7
Used to create a copy of the tree or get prefix expression. - 2. Inorder (Left, Root, Right):
4 → 2 → 5 → 1 → 6 → 3 → 7
Yields nodes in non-decreasing order in a BST. - 3. Postorder (Left, Right, Root):
4 → 5 → 2 → 6 → 7 → 3 → 1
Used to delete the tree (children deleted before parent). - 4. Level Order (BFS):
1 → 2 → 3 → 4 → 5 → 6 → 7
Traverses level by level using a Queue.
| Traversal Type | Time Complexity | Space Complexity (Recursive/Stack) | Space Complexity (Queue/BFS) |
|---|---|---|---|
| DFS (Pre, In, Post) | $O(N)$ | $O(H)$ where H is height | N/A |
| BFS (Level Order) | $O(N)$ | N/A | $O(W)$ where W is max width |
2. Core Tree Structures
Binary Tree
A tree whose elements have at most 2 children (left child and right child).
- Max Nodes at level L: $2^L$
- Max Nodes in tree of height H: $2^{H+1} - 1$
- Applications: Huffman coding, heaps, syntax trees.
class Node {
int data;
Node left, right;
public Node(int item) {
data = item;
left = right = null;
}
}Binary Search Tree (BST)
A node-based binary tree with the property: Left subtree nodes < Node < Right subtree nodes.
| Operation | Avg Case | Worst Case |
|---|---|---|
| Search | $O(\log N)$ | $O(N)$ (Degenerate) |
| Insert | $O(\log N)$ | $O(N)$ |
| Delete | $O(\log N)$ | $O(N)$ |
Interview Tip: Inorder traversal of a BST always returns a sorted array. Use this property to validate if a Binary Tree is a BST!
BST Search Implementation
def search_bst(root, val):
# Base Cases: root is null or key is present at root
if root is None or root.val == val:
return root
# Key is greater than root's key
if root.val < val:
return search_bst(root.right, val)
# Key is smaller than root's key
return search_bst(root.left, val)Ternary Search Tree (TST)
A type of trie (prefix tree) where nodes are arranged in a manner similar to a binary search tree, but with up to 3 children: left, mid, right. Extremely efficient for string representation.
- Structure: Left (smaller), Mid (equal), Right (greater).
- Applications: Spell checking, Auto-complete, Dictionary matching.
- Advantage: Much more space-efficient than standard Tries for sparsely populated string sets.
class TSTNode {
constructor(char) {
this.data = char;
this.isEndOfString = false;
this.left = null;
this.mid = null;
this.right = null;
}
}3. Self-Balancing Trees
Standard BSTs degrade to $O(N)$ operations if elements are inserted sequentially. Self-balancing trees automatically restructure themselves to maintain $O(\log N)$ height.
AVL Tree (Adelson-Velsky and Landis)
A strictly balanced BST where the difference between heights of left and right subtrees (Balance Factor) for every node cannot be more than 1 ($BF \in \{-1, 0, 1\}$).
Rotations (Rebalancing)
- LL (Left-Left): Right rotation.
- RR (Right-Right): Left rotation.
- LR (Left-Right): Left rotation on child, Right rotation on root.
- RL (Right-Left): Right rotation on child, Left rotation on root.
| Property | Complexity |
|---|---|
| Search / Insert / Delete | $O(\log N)$ strictly |
| Space | $O(N)$ (requires height storage) |
| Best Use Case | Read-heavy databases (fast lookups) |
Red-Black Tree
A self-balancing BST where each node has a color (Red or Black) acting as an extra bit of information used to ensure the tree remains approximately balanced during insertions and deletions.
The 5 Sacred Properties
- Every node is either Red or Black.
- The Root is always Black.
- Every Leaf (NIL) is Black.
- If a node is Red, both its children are Black (No two consecutive Red nodes).
- Every path from a node to its descendent leaves contains the same number of Black nodes (Black-Depth).
Use Case: Write-heavy apps. Used in Java's TreeMap, C++ std::map, and Linux Completely Fair Scheduler.
// Java standard library TreeMap uses Red-Black Tree internally
TreeMap<Integer, String> rbTree = new TreeMap<>();
rbTree.put(10, "Root");
rbTree.put(5, "Left Child"); // Auto-balances in O(log N)4. Advanced & Database Trees
Segment Tree
A specialized binary tree used for storing intervals or segments. It allows answering range queries (like range sum, range minimum/maximum) and updating elements in $O(\log N)$ time.
- Construction: Built bottom-up. Leaves represent array elements. Internal nodes represent merged results of children.
- Space: Requires $4N$ memory size array.
- Query: $O(\log N)$
- Update: $O(\log N)$
// Array representation is common
int tree[4 * MAX_N];
void build(int node, int start, int end) {
if(start == end) { tree[node] = arr[start]; return; }
int mid = (start + end) / 2;
build(2*node, start, mid);
build(2*node+1, mid+1, end);
tree[node] = tree[2*node] + tree[2*node+1]; // Range Sum
}N-ary Tree (Generic Tree)
A tree in which a node can have at most $N$ children. Binary trees are a special case where $N=2$.
Applications: File systems (folders can have many files/folders), Organizational charts, JSON/XML Document Object Model.
class NaryNode:
def __init__(self, val):
self.val = val
self.children = [] # List of NaryNodesB-Tree & B+ Tree
A self-balancing search tree designed to work well on magnetic disks or other direct-access secondary storage. Nodes can have multiple keys and multiple children, vastly reducing the height of the tree and minimizing disk I/O.
B-Tree Properties
- All leaves are at the same level.
- A B-Tree of order $m$ can have at most $m-1$ keys and $m$ children per node.
- B+ Tree Diff: All data is stored only at the leaf nodes (linked together as a linked list for fast range queries), internal nodes only store keys for routing.
| Feature | B-Tree | B+ Tree |
|---|---|---|
| Data Storage | Internal & Leaf | Leaf nodes only |
| Range Query | Slower | Extremely Fast (LinkedList) |
| Used In | MongoDB, PostgreSQL | MySQL (InnoDB) |
5. The Ultimate Cheat Sheet
Tree Comparison Matrix
| Tree Type | Search (Avg) | Insert (Avg) | Balancing | Primary Use Case / Real-World |
|---|---|---|---|---|
| BST | $O(\log N)$ | $O(\log N)$ | None | Basic sorted data, baseline structure |
| AVL Tree | $O(\log N)$ | $O(\log N)$ | Strict (Rotations) | Read-intensive apps (in-memory lookup tables) |
| Red-Black Tree | $O(\log N)$ | $O(\log N)$ | Loose (Color/Rotate) | Write-intensive apps (Java HashMaps/TreeMaps) |
| Trie (Prefix) | $O(K)$* | $O(K)$* | N/A | Autocomplete, Spellcheck, IP routing (*K=word len) |
| Segment Tree | $O(\log N)$ | $O(\log N)$ | Static Structure | Computational geometry, Range sum/min/max |
| B/B+ Tree | $O(\log N)$ | $O(\log N)$ | Split/Merge | Database Indexing, File Systems (NTFS, ext4) |
Decision Flowchart: Which Tree to Choose?
- Need to store strings for fast prefix search? ➔ Use Trie (or Ternary Tree to save space).
- Working with disk-based storage / databases? ➔ Use B+ Tree.
- Need fast range queries over an array? ➔ Use Segment Tree or Fenwick Tree.
- Need an in-memory balanced BST with frequent reads? ➔ Use AVL Tree.
- Need an in-memory balanced BST with frequent inserts/deletes? ➔ Use Red-Black Tree.
- Modeling hierarchical data (folders, DOM)? ➔ Use N-ary Tree.
Top 20 LeetCode Tree Patterns & Problems
Invert Binary Tree
Pattern: Post-order / Recursion
Maximum Depth of Binary Tree
Pattern: DFS / BFS
Diameter of Binary Tree
Pattern: DFS height calculation
Symmetric Tree
Pattern: Mirror Traversal
Subtree of Another Tree
Pattern: DFS nested traversal
Lowest Common Ancestor of a BST
Pattern: BST property logic
Binary Tree Level Order Traversal
Pattern: BFS with Queue (Size track)
Binary Tree Right Side View
Pattern: BFS (last element) / DFS
Construct Tree from Preorder & Inorder
Pattern: Hash Map + Array slicing
Validate Binary Search Tree
Pattern: Min/Max boundary passing
Kth Smallest Element in a BST
Pattern: In-order traversal (counter)
Lowest Common Ancestor of Binary Tree
Pattern: DFS returning Node
Binary Tree Maximum Path Sum
Pattern: DFS bottom-up accumulation
Serialize and Deserialize Binary Tree
Pattern: Pre-order String parsing
Vertical Order Traversal of a Tree
Pattern: BFS + Map (Row, Col)