Trie (Prefix Tree) ā Step-by-Step Word Insertion & Autocomplete
Module 11 ā Trie & Advanced: A tree built specifically for storing and searching strings Structured as Topic ā Plain-English Explanation ā Real Code ā Visual Diagram ā Complexity ā Common Pitfalls.
1. Trie Concept & Internal Architecture
A Trie (derived from "retrieval", pronounced "try") is an $m$-ary tree data structure where each node represents a character along a prefix path. Unlike a hash map, keys that share common prefixes share the same parent nodes in memory.
Key Structural Properties
- The root node represents an empty string
"". - Each node contains an array or hash map of pointers to child nodes (typically size 26 for lowercase English letters
'a'through'z'). - Each node maintains a boolean flag
isEndOfWordto distinguish between complete words and intermediate prefixes.
struct TrieNode {
TrieNode* children[26];
bool isEndOfWord;
TrieNode() {
isEndOfWord = false;
for (int i = 0; i < 26; i++) {
children[i] = nullptr;
}
}
};
Figure 11.1 ā Trie storing "cat", "car", "cap" sharing common prefix path "ca". Solid green dots mark isEndOfWord=true.
2. Complete C++ Implementation: Insert, Search & StartsWith
class Trie {
private:
TrieNode* root;
public:
Trie() {
root = new TrieNode();
}
// 1. Insert a word: O(L) Time, where L = word.length()
void insert(const string& word) {
TrieNode* curr = root;
for (char c : word) {
int idx = c - 'a';
if (!curr->children[idx]) {
curr->children[idx] = new TrieNode();
}
curr = curr->children[idx];
}
curr->isEndOfWord = true;
}
// 2. Search exact full word: O(L) Time
bool search(const string& word) {
TrieNode* curr = root;
for (char c : word) {
int idx = c - 'a';
if (!curr->children[idx]) return false;
curr = curr->children[idx];
}
return curr != nullptr && curr->isEndOfWord;
}
// 3. Prefix search (startsWith): O(P) Time, where P = prefix.length()
bool startsWith(const string& prefix) {
TrieNode* curr = root;
for (char c : prefix) {
int idx = c - 'a';
if (!curr->children[idx]) return false;
curr = curr->children[idx];
}
return true;
}
};
3. Autocomplete & Real-World System Use Cases
- Search Engine Autocomplete: Type
"algo"and the system traverses to node'o', then runs a lightweight DFS/BFS to collect top-ranked completions ("algorithm","algorand","algorithmic trading"). - Spell Checker & T9 Predictive Text: Validates whether a dictionary path exists in real-time.
- IP Routing (Longest Prefix Match): Binary Tries with bits 0 and 1 efficiently match subnet masks in high-speed hardware routers.
4. Trie vs Hash Table Comparison
| Metric | Trie (Prefix Tree) | Hash Table (unordered_set) |
|---|---|---|
| Lookup Time | $O(L)$ strictly guaranteed | $O(L)$ average, $O(n cdot L)$ worst case (hash collisions) |
| Prefix Search | $O(P)$ natural and instant | $O(n cdot L)$ brute-force full scan |
| Lexicographical Order | In-order traversal yields sorted output | Unordered, requires separate sorting |
| Memory Footprint | Higher (26 pointers per node) | Lower per-entry overhead |
Common Pitfall: Beginners often forget to check `curr->isEndOfWord` in `search()`. If you only check `curr != nullptr`, your search function will mistakenly return `true` for "app" when only "apple" was inserted into the Trie!
Practice Trie & Advanced MCQs
Master Trie & Advanced concepts with timed, competitive MCQs with detailed explanations.