A Trie (pronounced “try”) is a tree-based data structure used to store strings in a way that facilitates fast retrieval, typically for dictionary or prefix-based operations. Each node represents a character of a string, and strings are constructed by traversing the tree from the root to the leaf nodes.
Key Features of a Trie
- Efficient Search: Supports efficient prefix matching and searching.
- Insertions and Deletions: Insert and delete operations are straightforward.
- Space Optimization: Stores common prefixes only once, reducing redundancy.
Operations in a Trie
1. Insert Operation
- Insert a string into the Trie by adding its characters level by level.
- Mark the end of the word with a special flag (
is_end
).
2. Search Operation
- Search for a string by traversing the Trie based on its characters.
- Return
True
if all characters are found and theis_end
flag is set.
Trie Node Structure
Each node in the Trie contains:
- Children: A dictionary (or an array) to store references to child nodes.
- is_end: A boolean flag indicating whether the node represents the end of a word.
Implementation
1. Trie Node Class
class TrieNode:
def __init__(self):
self.children = {} # Dictionary to hold child nodes
self.is_end = False # Flag to indicate end of a word
2. Trie Class
class Trie:
def __init__(self):
self.root = TrieNode() # Root node of the Trie
# Insert a word into the Trie
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode() # Add a new node
node = node.children[char] # Move to the child node
node.is_end = True # Mark the end of the word
# Search for a word in the Trie
def search(self, word):
node = self.root
for char in word:
if char not in node.children:
return False # Character not found
node = node.children[char] # Move to the next node
return node.is_end # Return True if it's the end of a word
Usage Example
# Create a Trie
trie = Trie()
# Insert words into the Trie
trie.insert("apple")
trie.insert("app")
trie.insert("bat")
# Search for words
print(trie.search("apple")) # Output: True
print(trie.search("app")) # Output: True
print(trie.search("bat")) # Output: True
print(trie.search("cat")) # Output: False
Complexity Analysis
- Insert: O(L)O(L), where LL is the length of the word being inserted.
- Search: O(L)O(L), where LL is the length of the word being searched.
- Space: Depends on the number of words and their shared prefixes.
Advantages of a Trie
- Fast Prefix Matching: Ideal for autocomplete systems.
- Efficient for Dictionaries: Optimized for searching and storing words.
- Scalable: Handles large datasets effectively.
Applications of Trie
- Autocomplete: Predicts words based on input prefixes.
- Spell Checker: Suggests correct words for misspelled input.
- IP Routing: Efficiently matches IP prefixes.
- Dictionary Implementation: Stores and retrieves words quickly.
- Word Games: Used in games like Scrabble and Boggle for word validation.
A Trie is a versatile data structure that balances efficient searching and space optimization, making it invaluable for text-based applications.