To construct a trie data structure, we will need to create two classes: Trie and TrieNode.
The TrieNode class represents a single node in the trie, and it contains an array of TrieNode objects called links to represent the next possible characters in the trie. Each TrieNode also has a boolean property isEnd to mark the end of a word.
Here is an example implementation of the TrieNode class in Java:
1public class TrieNode {
2    private TrieNode[] links;
3    private boolean isEnd;
4
5    public TrieNode() {
6        links = new TrieNode[26];
7    }
8
9    public boolean containsKey(char ch) {
10        return links[ch - 'a'] != null;
11    }
12
13    public TrieNode get(char ch) {
14        return links[ch - 'a'];
15    }
16
17    public void put(char ch, TrieNode node) {
18        links[ch - 'a'] = node;
19    }
20
21    public boolean isEnd() {
22        return isEnd;
23    }
24
25    public void setEnd() {
26        isEnd = true;
27    }
28}The Trie class represents the trie itself and provides methods to insert a word, search for a word, and check if a word starts with a given prefix.
Here is an example implementation of the Trie class in Java:
1public class Trie {
2    private TrieNode root;
3
4    public Trie() {
5        root = new TrieNode();
6    }
7
8    public void insert(String word) {
9        TrieNode current = root;
10        
11        for (char ch : word.toCharArray()) {
12            if (!current.containsKey(ch)) {
13                current.put(ch, new TrieNode());
14            }
15            
16            current = current.get(ch);
17        }
18        
19        current.setEnd();
20    }
21
22    public boolean search(String word) {
23        TrieNode current = searchPrefix(word);
24        
25        return current != null && current.isEnd();
26    }
27
28    public boolean startsWith(String prefix) {
29        return searchPrefix(prefix) != null;
30    }
31
32    private TrieNode searchPrefix(String prefix) {
33        TrieNode current = root;
34        
35        for (char ch : prefix.toCharArray()) {
36            if (!current.containsKey(ch)) {
37                return null;
38            }
39            
40            current = current.get(ch);
41        }
42        
43        return current;
44    }
45}xxxxxxxxxx}public class Trie {    private TrieNode root;        public Trie() {        root = new TrieNode();    }        public void insert(String word) {        TrieNode current = root;                for (char ch : word.toCharArray()) {            if (!current.containsKey(ch)) {                current.put(ch, new TrieNode());            }                        current = current.get(ch);        }                current.setEnd();    }        public boolean search(String word) {        TrieNode current = searchPrefix(word);                return current != null && current.isEnd();    }        public boolean startsWith(String prefix) {        return searchPrefix(prefix) != null;Build your intuition. Is this statement true or false?
In a trie data structure, each node contains links to the next possible characters in the trie.
Press true if you believe the statement is correct, or false otherwise.
To insert a new word into a trie, we can use the following steps:
- Start from the root node and initialize a pointer 
currentto track the current node. - Iterate through each character in the word.
 - Check if the current node contains a link for the character. If not, create a new node and add the character as a link.
 - Update the 
currentpointer to the newly created node. - Repeat steps 3-4 for all characters in the word.
 - After iterating through all characters, mark the 
currentnode as the end of a word. 
Here is an example implementation of the insert method in the Trie class:
1public void insert(String word) {
2    TrieNode current = root;
3
4    for (int i = 0; i < word.length(); i++) {
5        char ch = word.charAt(i);
6
7        if (!current.containsKey(ch)) {
8            current.put(ch, new TrieNode());
9        }
10
11        current = current.get(ch);
12    }
13
14    current.setEnd();
15}xxxxxxxxxx// Implementing Trie Insertionpublic class Trie {    private TrieNode root;    public Trie() {        root = new TrieNode();    }    public void insert(String word) {        TrieNode current = root;        for (int i = 0; i < word.length(); i++) {            char ch = word.charAt(i);            if (!current.containsKey(ch)) {                current.put(ch, new TrieNode());            }            current = current.get(ch);        }        current.setEnd();    }}Build your intuition. Click the correct answer from the options.
Which of the following steps are involved in inserting a new word into a trie?
A) Traverse the trie until the end of the word B) Start from the root node and initialize a pointer C) Create a new node for each character D) Mark the last node as the end of the word
Select the correct options:
Click the option that best answers the question.
In a trie, deletion refers to removing a word from the trie.
The deletion operation can be done by following these steps:
- Start from the root node and initialize a pointer 
currentto track the current node. - Iterate through each character in the word.
 - Check if the current node contains a link for the character. If not, return false as the word is not present in the trie.
 - Update the 
currentpointer to the next node. - Repeat steps 3-4 for all characters in the word.
 - After iterating through all characters, check if the 
currentnode is the end of a word. If not, return false as the word is not present in the trie. - Mark the 
currentnode as not the end of a word. - Check if the 
currentnode has any children. If not, remove the link to thecurrentnode from its parent. - Repeat steps 7-8 for all characters in the word, from the last character to the first.
 
Here is an example implementation of the delete method in the Trie class:
1public void delete(String word) {
2    delete(root, word, 0);
3}
4
5private boolean delete(TrieNode current, String word, int index) {
6    if (index == word.length()) {
7        if (!current.isEndOfWord()) {
8            return false;
9        }
10        current.setEndOfWord(false);
11        return current.getChildren().isEmpty();
12    }
13
14    char ch = word.charAt(index);
15    TrieNode node = current.getChildren().get(ch);
16    if (node == null) {
17        return false;
18    }
19
20    boolean shouldDeleteCurrentNode = delete(node, word, index + 1);
21    if (shouldDeleteCurrentNode) {
22        current.getChildren().remove(ch);
23        return current.getChildren().isEmpty();
24    }
25
26    return false;
27}xxxxxxxxxx}class TrieNode {    private Map<Character, TrieNode> children;    private boolean isEndOfWord;    public TrieNode() {        children = new HashMap<>();        isEndOfWord = false;    }    public Map<Character, TrieNode> getChildren() {        return children;    }    public boolean isEndOfWord() {        return isEndOfWord;    }    public void setEndOfWord(boolean endOfWord) {        isEndOfWord = endOfWord;    }}class Trie {    private TrieNode root;    public Trie() {        root = new TrieNode();    }Try this exercise. Is this statement true or false?
In a trie, deletion refers to removing a word from the trie.
Press true if you believe the statement is correct, or false otherwise.
To search for a word in a trie, follow these steps:
- Start from the root node and initialize a pointer 
currentto track the current node. - Iterate through each character in the word.
 - Check if the current node contains a link for the character. If not, the word is not present in the trie.
 - Update the 
currentpointer to the next node. - Repeat steps 3-4 for all characters in the word.
 - After iterating through all characters, check if the 
currentnode marks the end of a word. If yes, the word is present in the trie. Otherwise, the word is not present. 
Here is an example implementation of the search method in the Trie class:
xxxxxxxxxxclass Trie {    // ... other methods    public boolean search(String word) {        TrieNode current = root;        for (int i = 0; i < word.length(); i++) {            char ch = word.charAt(i);            TrieNode node = current.getChildren().get(ch);            // If the current node doesn't contain a link for the character,            // the word is not present in the trie            if (node == null) {                return false;            }            current = node;        }        // After iterating through all characters,        // the word is present if the current node marks the end of a word        return current.isEndOfWord();    }    // ... other methods}Let's test your knowledge. Click the correct answer from the options.
What is the time complexity of searching for a word in a trie with n nodes?
Click the option that best answers the question.
- O(log n)
 - O(n)
 - O(m)
 - O(1)
 
A practical use case of tries is autocomplete functionality. Tries provide an efficient way to implement autocomplete or suggestion features in text editors or search engines.
In an autocomplete system, given a prefix entered by the user, the system needs to suggest a list of words that match that prefix. For example, if the user types "app", the system should suggest words like "apple" and "application".
Tries are well-suited for this task because they can efficiently find all words that match a given prefix. Starting from the root node, we can navigate through the trie following the characters in the prefix. If we reach a node where the characters don't match, we can immediately stop the traversal and return an empty list of suggestions. If we reach the end of the prefix, we can use a depth-first search to find all words below that node, which provides us with the autocomplete suggestions.
Here's an example implementation of an autocomplete class using a trie in Java:
1import java.util.ArrayList;
2import java.util.List;
3
4public class Autocomplete {
5
6    private TrieNode root;
7
8    public Autocomplete() {
9        root = new TrieNode();
10    }
11
12    // Insert a word into the trie
13    public void insert(String word) {
14        TrieNode current = root;
15
16        for (char c : word.toCharArray()) {
17            int index = c - 'a';
18            if (current.children[index] == null) {
19                current.children[index] = new TrieNode();
20            }
21            current = current.children[index];
22        }
23
24        current.isWord = true;
25    }
26
27    // Get autocomplete suggestions for a given prefix
28    public List<String> autocomplete(String prefix) {
29        TrieNode current = root;
30        List<String> suggestions = new ArrayList<>();
31
32        for (char c : prefix.toCharArray()) {
33            int index = c - 'a';
34            if (current.children[index] == null) {
35                return suggestions;
36            }
37            current = current.children[index];
38        }
39
40        autocompleteHelper(prefix, current, suggestions);
41
42        return suggestions;
43    }
44
45    private void autocompleteHelper(String prefix, TrieNode node, List<String> suggestions) {
46        if (node.isWord) {
47            suggestions.add(prefix);
48        }
49
50        for (char c = 'a'; c <= 'z'; c++) {
51            int index = c - 'a';
52            if (node.children[index] != null) {
53                autocompleteHelper(prefix + c, node.children[index], suggestions);
54            }
55        }
56    }
57
58    private class TrieNode {
59        TrieNode[] children;
60        boolean isWord;
61
62        public TrieNode() {
63            this.children = new TrieNode[26];
64            this.isWord = false;
65        }
66    }
67
68    public static void main(String[] args) {
69        Autocomplete autocomplete = new Autocomplete();
70        autocomplete.insert("apple");
71        autocomplete.insert("application");
72        autocomplete.insert("banana");
73
74        List<String> suggestions = autocomplete.autocomplete("app");
75        System.out.println(suggestions); // Output: [apple, application]
76    }
77}xxxxxxxxxx}```javaimport java.util.ArrayList;import java.util.List;public class Autocomplete {    private TrieNode root;    public Autocomplete() {        root = new TrieNode();    }    // Insert a word into the trie    public void insert(String word) {        TrieNode current = root;        for (char c : word.toCharArray()) {            int index = c - 'a';            if (current.children[index] == null) {                current.children[index] = new TrieNode();            }            current = current.children[index];        }        current.isWord = true;    }    // Get autocomplete suggestions for a given prefix    public List<String> autocomplete(String prefix) {Build your intuition. Is this statement true or false?
Tries are efficient data structures for implementing autocomplete functionality in text editors or search engines.
Press true if you believe the statement is correct, or false otherwise.
Generating complete for this lesson!



