A Trie stores strings character by character in a tree, making it easy to find all keys sharing a prefix by traversing the tree. A Hash Map stores whole keys and cannot efficiently find keys by prefix without checking all keys.
class TrieNode { public Dictionary<char, TrieNode> Children = new Dictionary<char, TrieNode>(); public bool IsWord = false; } class Trie { private TrieNode root = new TrieNode(); public void Insert(string word) { var node = root; foreach (var ch in word) { if (!node.Children.ContainsKey(ch)) { node.Children[ch] = new TrieNode(); } node = node.Children[ch]; } node.IsWord = true; } public bool StartsWith(string prefix) { var node = root; foreach (var ch in prefix) { if (!node.Children.ContainsKey(ch)) return false; node = node.Children[ch]; } return true; } } var trie = new Trie(); trie.Insert("apple"); trie.Insert("app"); Console.WriteLine(trie.StartsWith("app")); Console.WriteLine(trie.StartsWith("apl"));
The prefix "app" exists because "app" and "apple" were inserted. The prefix "apl" does not exist in the Trie, so it returns false.
var dict = new Dictionary<string, int> { {"apple", 1}, {"app", 2}, {"banana", 3} }; bool HasPrefix(string prefix) { foreach (var key in dict.Keys) { if (key.StartsWith(prefix)) { return true; } } return false; } Console.WriteLine(HasPrefix("app"));
The code works correctly but is inefficient for large dictionaries because it must check every key to find a prefix match. This is why Trie is better for prefix search.
class TrieNode { public Dictionary<char, TrieNode> Children = new Dictionary<char, TrieNode>(); public bool IsWord = false; } class Trie { private TrieNode root = new TrieNode(); public void Insert(string word) { var node = root; foreach (var ch in word) { if (!node.Children.ContainsKey(ch)) { node.Children[ch] = new TrieNode(); } node = node.Children[ch]; } node.IsWord = true; } public bool Search(string word) { var node = root; foreach (var ch in word) { if (!node.Children.ContainsKey(ch)) return false; node = node.Children[ch]; } return node.IsWord; } } var trie = new Trie(); trie.Insert("cat"); trie.Insert("car"); trie.Insert("cart"); Console.WriteLine(trie.Search("car")); Console.WriteLine(trie.Search("cart")); Console.WriteLine(trie.Search("ca"));
"car" and "cart" were inserted as words, so Search returns true. "ca" is only a prefix, not a word, so Search returns false.
Trie nodes represent characters and shared prefixes, so all words with a prefix are grouped under the same subtree. Hash Map stores whole keys without prefix grouping, so it must check all keys for autocomplete.
