This repository has been archived by the owner on Feb 21, 2020. It is now read-only.
forked from kayoumido/ASD2_LABO5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTernarySearchTrie.h
196 lines (160 loc) · 4.59 KB
/
TernarySearchTrie.h
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/**
* Authors: Robin Demarta, Loïc Dessaules, Doran Kayoumi
* File: TernarySearchTrie.h
* Date: 10.01.2019
*/
#ifndef LABO05_TERNARYSEARCHTRIE_H
#define LABO05_TERNARYSEARCHTRIE_H
#include <string>
#include "AVLTree.h"
class TernarySearchTrie {
struct Node {
public:
// Subtrees
Node* left;
Node* middle;
Node* right;
char value;
bool endOfWorld; // Indicates that this node (char) is the end of a word
int nodeHeight;
int nodeSize;
Node(Node* left, Node* middle, Node* right, char value, bool endOfWorld)
: left(left), middle(middle), right(right), value(value), endOfWorld(endOfWorld), nodeSize(1), nodeHeight(0) {}
};
Node* root;
public:
TernarySearchTrie() {
root = nullptr;
}
~TernarySearchTrie() {
deleteSubTree(root);
}
/**
* Recursive function to delete all subtree nodes
* @param x
*/
void deleteSubTree(Node* x) {
if(x == nullptr) return;
deleteSubTree(x->right);
deleteSubTree(x->left);
deleteSubTree(x->middle);
delete x;
}
/**
* Public function to insert a new word in the TST
* @param word
*/
void insert(const std::string& word) {
root = insertInTrie(root, word);
}
/**
* Public function to check if a word exists in the TST
* @param word
* @return
*/
bool find(const std::string& word) {
return findInTrie(root, word);
}
private:
/**
* Recursive function to find an existing word
* @return
*/
bool findInTrie(Node* node, std::string word) {
if(node == nullptr)
return false;
if(word[0] < node->value)
// Left
return findInTrie(node->left, word);
if(word[0] > node->value)
// Right
return findInTrie(node->right, word);
if(word.length() == 1)
// Last letter: must be end of the word
return node->endOfWorld;
// Middle (remove first letter and continue)
return findInTrie(node->middle, word.substr(1, word.length() - 1));
}
/**
* Recursive function to insert a new word
* @param node
* @param word
*/
Node* insertInTrie(Node* node, std::string word) {
if(node == nullptr)
// Empty: insert node
node = new Node(nullptr, nullptr, nullptr, word[0], false);
if(word[0] < node->value)
// Left
node->left = insertInTrie(node->left, word);
else if(word[0] > node->value)
// Right
node->right = insertInTrie(node->right, word);
else
// Middle
if(word.length() == 1)
// No more letters
node->endOfWorld = true;
else
// Same letter: ignore it and continue
node->middle = insertInTrie(node->middle, word.substr(1, word.length() - 1));
updateNodeSize(node);
return restoreBalance(node);
}
/* The following functions have been taken from the AVLTree file */
int height(Node* x) {
if ( x == nullptr )
return -1;
return x->nodeHeight;
}
int balance(Node* x) {
if(x==nullptr) return 0;
return height(x->left) - height(x->right);
}
Node* restoreBalance(Node* x) {
if(balance(x) < -1) // left < right-1
{
if (balance(x->right)>0)
x->right = rotateRight( x->right );
x = rotateLeft(x);
}
else if( balance(x) > 1) // left > right+1
{
if ( balance(x->left) < 0 )
x->left = rotateLeft( x->left );
x = rotateRight(x);
}
else updateNodeHeight(x);
return x;
}
void updateNodeHeight(Node* x) {
x->nodeHeight = std::max(height(x->right),height(x->left)) + 1;
}
Node* rotateRight(Node* x) {
Node* y = x->left;
x->left = y->right;
y->right = x;
y->nodeSize = x->nodeSize;
updateNodeSize(x);
updateNodeHeight(x);
updateNodeHeight(y);
return y;
}
Node* rotateLeft(Node* x) {
Node* y = x->right;
x->right = y->left;
y->left = x;
y->nodeSize = x->nodeSize;
updateNodeSize(x);
updateNodeHeight(x);
updateNodeHeight(y);
return y;
}
void updateNodeSize(Node* x) {
x->nodeSize = size(x->right) + size(x->left) + 1;
}
int size(Node* x) {
return ( x == nullptr ) ? 0 : x->nodeSize;
}
};
#endif //LABO05_TERNARYSEARCHTRIE_H