class TrieNode {
constructor() {
this.children = new Map();
this.isEndOfWord = false;
}
}
class Trie {
constructor() {
this.root = new TrieNode();
}
insert(word) {
let node = this.root;
for (const char of word) {
if (!node.children.has(char)) {
node.children.set(char, new TrieNode());
}
node = node.children.get(char); // advance to child node
}
node.isEndOfWord = true; // mark end of word
}
searchPrefix(prefix) {
let node = this.root;
for (const char of prefix) {
if (!node.children.has(char)) {
return null; // prefix not found
}
node = node.children.get(char); // advance to next node
}
return node; // node at end of prefix
}
collectAllWords(node, prefix, words) {
if (node.isEndOfWord) {
words.push(prefix); // found a complete word
}
for (const [char, childNode] of node.children) {
this.collectAllWords(childNode, prefix + char, words); // explore deeper
}
}
prefixSearch(prefix) {
const node = this.searchPrefix(prefix);
if (!node) return [];
const words = [];
this.collectAllWords(node, prefix, words); // gather all words below prefix
return words;
}
}
// Driver code
const trie = new Trie();
['apple', 'app', 'apt', 'bat'].forEach(word => trie.insert(word));
const prefix = 'ap';
const results = trie.prefixSearch(prefix);
console.log(`Words starting with '${prefix}': ${results.join(', ')}`);node = node.children.get(char); // advance to child node
advance node pointer to next letter node
node.isEndOfWord = true; // mark end of word
mark current node as end of a valid word
if (!node.children.has(char)) { return null; }
stop search if prefix letter not found
this.collectAllWords(childNode, prefix + char, words);
recursively collect all words below current node
Words starting with 'ap': app, apple, apt