-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTrie.cpp
135 lines (120 loc) · 4.49 KB
/
Trie.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Assuming to store strings only containing A-Z without any space i.e. word
#include <iostream>
using namespace std;
// Structure for the Node of the Trie
struct TrieNode
{
bool is_entry; // Checking if the entry is valid on a particular node or not
TrieNode *children[26]; // For storing 26 Alphabets of english
};
// Wrapper structure for the Trie
struct Trie
{
TrieNode *root; // Create this root node whenever declare any Trie, whose is_entry equals to false
};
// Helper Function for finding the index of the children of the Trie node
int LetterToIndex(char letter)
{
return letter - 65; // As A->0 && Z->25
}
// Function for searching for the target in the Trie
TrieNode *TrieNodeSearch(TrieNode *current, string target, int index)
{
if (index == target.length()) // Checking if the target node is at the current depth or not
{
if (current->is_entry) // If yes checking if it is a valid node or not
{
return current;
}
else // There is no valid node at this depth for the target we are searching
{
return NULL;
}
}
char next_letter = target[index]; // Finding the next letter for the node
int next_index = LetterToIndex(next_letter); // Finding the next children index where the next character points to in the Trie
TrieNode *next_child = current->children[next_index]; // Storing the child for the current node in a variable
if (next_child == NULL) // Checking if the child is valid or not
{
return NULL;
}
else
{
return TrieNodeSearch(next_child, target, index + 1); // Recussive call for searching the next character
}
}
// Wrapper function for TrieNodeSearch
TrieNode *TrieSearch(Trie trie, string target)
{
return TrieNodeSearch(trie.root, target, 0);
}
// Fuction for Insertion of the nod in a Trie
void TrieNodeInsert(TrieNode *current, string new_value, int index)
{
if (index == new_value.length()) // Checking if the current node is at current depth or not if yes marking its entry as valid
{
current->is_entry = true;
}
else
{
char next_letter = new_value[index]; // Storing the next letter of the string
int next_index = LetterToIndex(next_letter); // Finding the index for the children subtree
TrieNode *next_child = current->children[next_index]; // Storing the point to the next child
if (next_child == NULL) // Checking if the child node already exists or not
{
current->children[next_index] = new TrieNode; // If not creating the new child node
TrieNodeInsert(current->children[next_index], new_value, index + 1); // Calling the recursive call to make next character node
}
else
{
TrieNodeInsert(next_child, new_value, index + 1); // If yes calling the fuction for crateing next character node
}
}
}
// Wrapper function for inserting the node in the Trie
void TrieInsert(Trie trie, string new_value)
{
return TrieNodeInsert(trie.root, new_value, 0);
}
// Function to delete the node of the Trie
bool TrieNodeDelete(TrieNode *current, string target, int index)
{
if (index == target.length()) // Checking if we have to remove the node is at correct depth or not
{
if (current->is_entry)
{
current->is_entry = false;
}
}
else // Traversing to down to the trie same as search and insert
{
char next_letter = target[index];
int next_index = LetterToIndex(next_letter);
TrieNode *next_child = current->children[next_index];
if (next_child != NULL)
{
if (TrieNodeDelete(next_child, target, index + 1))
{
current->children[next_index] = NULL;
}
}
}
//#Do not delete this node if it has either an entry or a child
if (current->is_entry) // If current node is a valid node
{
return false;
}
for (auto x : current->children) //Checking if any sub-node/children node is a valid node or not.
{
if (x != NULL)
{
return false;
}
}
return true;
}
// Wrapper Function to delete the node from the Trie
void TrieDelete(Trie tr, string target)
{
TrieNodeDelete(tr.root, target, 0);
}