Skip to main content

Trie

SpaceTime
AccessLookupInsertionDeletion
O(n)N/AO(n)O(n)O(n)

Definition​

Trie is a tree-like data structure used to store and efficiently retrieve strings.

Simplified

Trie as a kind of magical tree. But instead of having fruits or leaves, this tree has letters on each branch. Now, suppose you want to find a word. You start at the root of the tree and follow the branches that have the letters of your word in order. If you can reach the end of your word by following the branches, voila, the word is in the tree!

For example, if you're looking for the word "cat", you'd start at the root, find a branch with the letter 'c', then from there find a branch with 'a', and finally a branch with 't'. If all these branches exist in the correct order, the word "cat" is in your tree.

This magical tree is super efficient and can help you find words really quickly, even if you have a dictionary's worth of words in your tree. That's why it's used in software engineering, especially in tasks like word suggestions and spell checks. It's like having a super-powered dictionary.

Practice​

AspectPseudo Code
Insertion
add_word(word)
current_node = root
for char in word:
current_node = current_node.children[char] ?: TrieNode()
current_node.is_end_of_word = True
Deletion Recursive
delete_word(word)
delete_word(root, word, 0)

delete_word(current_node, word, index)
if current_node == ø:
return False
if index == word.length:
if !current_node.is_end_of_word:
return False
current_node.is_end_of_word = false
return current_node.children == ø
char = word[index]
next_node = current_node.children[char] ?: return false
should_delete_current_node = delete_word(next_node, word, index + 1)
if should_delete_current_node:
current_node.children.remove(char)
return current_node.children == ø
Deletion Iterative
delete_word_iterative(word)
current_node = root
index = 0
nodes_stack = Stack<Pair<TrieNode, Int>>()

while index < word.length:
char = word[index]
next_node = current_node.children[char]

if next_node == ø:
return

nodes_stack.add(Pair(current_node, index))
current_node = next_node
index++

current_node.is_end_of_word = false

while nodes_stack != ø:
parentNode, parentIndex = nodes_stack.pop()

if current_node.children == ø and not current_node.is_end_of_word:
parentNode.children.remove(word[parentIndex])

current_node = parentNode
Suggest Next Characters Recursive
suggest_next_characters(prefix)
lastNode = get_last_character_node(prefix)
suggestions = List<Char>()

if lastNode != ø:
suggest_next_characters(lastNode, prefix, suggestions)

return suggestions

suggest_next_characters(node, currentPrefix, suggestions)
if node.is_end_of_word:
suggestions.add(currentPrefix[currentPrefix.length - 1])

for char, child_node in node.children:
suggest_next_characters(child_node, currentPrefix + char, suggestions)
Suggest Next Characters Iterative
suggest_next_characters_iterative(prefix)
suggestions = List<Char>()
current_node = root
currentPrefix = ""

for char in prefix:
current_node = current_node.children[char] ?: return suggestions
currentPrefix += char

stack = Stack<Pair<TrieNode, String>>()
stack.add(Pair(current_node, currentPrefix))

while stack != ø:
node, current = stack.pop()

if node.is_end_of_word:
suggestions.add(current.last())

for char, child_node in node.children:
stack.add(Pair(child_node, current + char))

return suggestions
Search
does_word_exist(word)
lastNode = get_last_character_node(word)
return lastNode?.is_end_of_word ?: false
Starts with
starts_with(prefix)
return get_last_character_node(prefix) != ø

get_last_character_node(prefix)
current_node = root

for char in prefix:
current_node = current_node.children[char] ?: return ø

return current_node