Lookup Does Not Care How Many Words You Have
Compare that with a balanced BST at O(L log n), where n is the dictionary size.
Prefix Queries Are the Real Superpower
A hash table can beat a trie for exact lookup — O(L) to hash versus O(L) to walk, with a smaller constant. But a hash table cannot answer "which words start with 'car'?" without scanning everything.
A trie answers it structurally: walk to the node for "car", then collect every word in the subtree beneath it. Press Autocomplete prefix and watch the subtree light up. That single property is why tries power search suggestions, IDE completion, and routing tables.
Marking Where Words End
Not every node is a word. Inserting "car" and "care" means "car" ends partway down the path to "care", so each node carries an is-word flag, drawn here as a filled circle.
Without it you could not tell whether a path spells a real word or merely a prefix of one — and searching for "ca" would wrongly succeed.
The Cost: Memory
Tries trade space for speed. A naive implementation gives every node an array of 26 child pointers, most of them null — enormously wasteful on sparse dictionaries.
Practical fixes: use a hash map of children instead of a fixed array, or switch to a radix tree (compressed trie), which merges chains of single-child nodes into one edge holding a whole substring. That is what IP routing tables use.
Watch the "saved by sharing" figure as you add words with common prefixes — sharing is what claws some of that memory back.
What it does that a hash table cannot
A hash set answers "is this exact string present?" in O(1). A trie answers several questions a hash set cannot answer at all.
| Query | Trie | Hash set |
|---|
| Exact lookup | O(m) | O(1) average |
| Does any word start with this prefix? | O(m) | O(n) — scan everything |
| All words with this prefix | O(m + output) | O(n) |
| Longest prefix of this string that is a word | O(m) | Not directly |
| Lexicographic iteration | Natural | Requires sorting |
| Fuzzy match within edit distance k | Feasible | Not directly |
The prefix rows are the point. Autocomplete needs "all words starting with 'car'", and a trie walks three nodes and then collects the subtree. A hash set has no structure to exploit and must examine every key.
The longest-prefix match row matters in networking: IP routing tables answer "which routing rule has the longest matching prefix for this address?" and a trie over address bits does it in one pass. That is what a radix trie in a router is doing.
Space, and the two compressed variants
A naive trie is memory-hungry: one node per character per distinct prefix, and each node carries a dictionary. Storing a large English dictionary can use more memory than the strings themselves.
Two standard compressions:
Radix trie (Patricia trie) merges chains of single-child nodes into one edge labelled with a substring. A trie storing only "internationalisation" becomes two nodes rather than twenty-one. This is the variant used in routing tables and in some database indexes.
DAWG (directed acyclic word graph) also merges identical suffixes, so "running" and "jumping" share their "ing" ending. Far smaller, and it cannot store values per word, so it suits membership testing rather than mapping.
| Structure | Space | Supports values |
|---|
| Standard trie | Largest | Yes |
| Radix trie | Much smaller | Yes |
| DAWG | Smallest | No |
For most applications a standard trie with dictionary children is fine, and a radix trie is worth the extra complexity when the key set is large and shares long prefixes.
Things to try with Trie
- Load the sample words and note how car, card, care and careful all share one path for 'c-a-r'.
- Insert a word starting with a new letter. A whole new branch appears from the root — nothing to share.