8: Tries
A trie stores strings character-by-character. Strings with common prefixes share paths. Operations are where is string length—independent of how many strings are stored.
Data Structure
TrieNode:
- key: Key
- val: Object # non-None marks end of word
- children: Dictionary[String, TrieNode]
Trie:
- root: Optional[TrieNode]Operations
Insert
insert(key, val):
node = root
for char in key:
if char not in node.children:
node.children[char] = TrieNode(char, None)
node = node.children[char]
node.val = val # mark end of wordSearch
get(key):
node = root
for char in key:
if char not in node.children:
return None
node = node.children[char]
return node if node.val is not None else NonePrefix Search
starts_with(prefix):
node = root
for char in prefix:
if char not in node.children:
return False
node = node.children[char]
return TrueAutocomplete
autocomplete(prefix):
node = root
for char in prefix:
if char not in node.children:
return []
node = node.children[char]
return collect_all_words(node, prefix)Runtime
| Operation | Time |
|---|---|
| Insert | |
| Search | |
| Delete | |
| Prefix search | |
| Autocomplete |
= string length, = total chars in results.
Space: worst case, better with shared prefixes.
Trie vs Hash Table vs BST
| Trie | Hash Table | BST | |
|---|---|---|---|
| Search | avg | ||
| Prefix search | complex |
Tries win for prefix operations.
Key Insight
Operations depend on string length , not on number of strings . Prefix operations are trivial: walk to the prefix node, and all descendants are matches.