Menu
Coddy logo textTech

Trie (Prefix Tree)

Last updated

A trie (pronounced "try"), or prefix tree, stores a set of strings by their characters: each edge is labeled with a character, and a path from the root spells out a prefix. Words that share a prefix share the same nodes, so "car", "card", and "care" all reuse the c-a-r path. Press play above to watch words get inserted one character at a time, branching only where they differ.

Because lookups walk one node per character, searching for a word of length m takes O(m) time regardless of how many words the trie holds. That makes tries ideal for autocomplete, spell-checking, and prefix search.

Time & space complexity

OperationComplexityNotes
InsertO(m)m = length of the word
SearchO(m)One step per character
Prefix queryO(m)Walk to the prefix node
SpaceO(total chars)Shared prefixes stored once

Step by step (insert)

StepWhat happens
1Start at the root node.
2For each character in the word, look for a matching child edge.
3If it exists, follow it (reusing the shared prefix).
4If not, create a new child node for that character.
5After the last character, mark that node as end-of-word.

Worked example

Inserting ["car", "card", "care"] into an empty trie:

StepStructureAction
Insert carroot → c → a → r✓No matching children exist, so create c, a, r and mark r as end-of-word.
Insert cardroot → c → a → r✓ → d✓Reuse the existing c-a-r path, then create one new child d and mark it end-of-word.
Insert careroot → c → a → r✓ → {d✓, e✓}Reuse c-a-r, branch off r with a new child e, and mark e end-of-word.
Search careroot → c → a → r → e✓Walk c, a, r, e; the final node is marked end-of-word, so care is present.
Search caroot → c → aThe path exists but a is not marked end-of-word, so ca is a prefix but not a stored word.

When to use a trie

Use it whenAvoid it when
You need prefix queries or autocomplete over a set of strings.You only need whole-key lookups - a hash table is faster and lighter.
Many stored words share common prefixes, so nodes are reused.Keys are long and rarely overlap, wasting one node per character.
You want keys returned in sorted order via traversal.Memory is tight - per-node child pointers add significant overhead.
Lookup cost must depend on key length, not dataset size.The alphabet is huge (e.g. full Unicode) and children are stored densely.

Trie (Prefix Tree) code

A clean, runnable Trie (Prefix Tree) implementation in Python, JavaScript, Java, C++, C. Pick a language, copy the code, or open it pre-loaded in the Coddy Playground.

Trie (Prefix Tree) code in Python

Python
1class TrieNode:2    def __init__(self):3        self.children = {}4        self.is_word = False5
6
7class Trie:8    def __init__(self):9        self.root = TrieNode()10
11    def insert(self, word):12        node = self.root13        for ch in word:14            node = node.children.setdefault(ch, TrieNode())15        node.is_word = True16
17    def search(self, word):18        node = self._walk(word)19        return node is not None and node.is_word20
21    def starts_with(self, prefix):22        return self._walk(prefix) is not None23
24    def _walk(self, s):25        node = self.root26        for ch in s:27            if ch not in node.children:28                return None29            node = node.children[ch]30        return node31
32
33trie = Trie()34for word in ["car", "card", "care", "dog"]:35    trie.insert(word)36
37print("search(card):     ", trie.search("card"))38print("search(ca):       ", trie.search("ca"))39print("starts_with(ca):  ", trie.starts_with("ca"))40print("starts_with(do):  ", trie.starts_with("do"))41print("starts_with(cat): ", trie.starts_with("cat"))
Run this code in the Python Playground

Trie FAQ

What is a trie used for?
Tries power prefix-based features: autocomplete and search suggestions, spell-checkers, IP routing tables, and dictionary lookups. Anywhere you need fast "does any stored word start with this prefix?" queries, a trie shines.
What is the time complexity of a trie?
Insert, search, and prefix queries all run in O(m) time, where m is the length of the word or prefix - independent of how many words are stored. The trade-off is memory: a trie can use a lot of space, though shared prefixes are stored only once.
What is the difference between a trie and a hash table?
A hash table offers O(1) average lookup of whole keys but can't answer prefix queries. A trie is slightly slower per lookup but naturally supports prefix search, ordered traversal, and autocomplete - the reason it's preferred for those use cases.
When should I use a trie instead of a binary search tree?
Use a trie when your keys are strings and you need prefix lookups: it runs in O(m) per operation on the key length, while a balanced BST costs O(m log n) because each comparison scans the string and there are log n of them. A BST is the better choice when keys aren't string-like or when memory overhead matters more than prefix speed.
How do you handle the end of a word in a trie?
Each node carries an end-of-word flag that is set only when a full inserted word terminates there. Without it you couldn't tell a stored word from a mere prefix - for example after inserting card, the node for car exists but should only be reported as a word if car was also inserted.
Do tries always save memory by sharing prefixes?
Not always. Sharing helps only when many keys overlap; with long, distinct keys a trie can use far more memory than a hash set, since every character becomes its own node with child pointers. If space is the concern, a compressed radix tree merges single-child chains to cut that overhead.
Coddy programming languages illustration

Master algorithms with Coddy

GET STARTED