AlgoPlus v0.1.0
Loading...
Searching...
No Matches
234_tree.h
1#ifndef TWOTHREEFOUR_TREE_H
2#define TWOTHREEFOUR_TREE_H
3
4#ifdef __cplusplus
5#include <algorithm>
6#include <iostream>
7#include <memory>
8#include <queue>
9#include <unordered_map>
10#include <vector>
11#endif
12
16template <typename T> class ttf_tree {
17 private:
26 typedef struct node {
27 std::vector<T> keys;
28 std::vector<std::shared_ptr<node>> children;
29 int numChildren;
30 int index{};
31 node(std::vector<T> keys, std::vector<std::shared_ptr<node>> children, int numChildren)
32 : keys(keys), children(children), numChildren(numChildren) {}
33 } node;
34
35 std::shared_ptr<node> root;
36 std::unordered_map<std::shared_ptr<node>, std::shared_ptr<node>> parent;
37
38 public:
44 explicit ttf_tree(const std::vector<T>& elements = {}) {
45 if (!elements.empty()) {
46 for (const T& x : elements) {
47 this->insert(x);
48 }
49 }
50 }
51
58 bool search(const T& key) const;
59
64 void insert(const T& key);
65
71 std::vector<std::vector<std::vector<T>>> level_order() const;
72
76 friend std::ostream& operator<<(std::ostream& out, ttf_tree<T>& t) {
77 std::vector<std::vector<std::vector<T>>> level_ordered = t.level_order();
78 for (auto& x : level_ordered) {
79 for (auto& y : x) {
80 out << '[';
81 for (int i = 0; i < y.size(); i++) {
82 if (i != y.size() - 1) {
83 out << y[i] << ", ";
84 } else {
85 out << y[i] << "], ";
86 }
87 }
88 }
89 out << '\n';
90 }
91 return out;
92 }
93};
94
95template <typename T> inline void ttf_tree<T>::insert(const T& key) {
96 std::vector<std::shared_ptr<node>> null_children(4, nullptr);
97 if (root == nullptr) {
98 std::vector<int> keys = {key};
99 root = std::make_shared<node>(keys, null_children, 2);
100 root->index = 0;
101 parent[root] = nullptr;
102 return;
103 } else {
104 std::shared_ptr<node> head = root;
105 while (head != nullptr) {
106 if (head->numChildren == 2) { // case for 2-node
107 if (head->children[0] == nullptr && head->children[1] == nullptr) {
108 head->keys.push_back(key);
109 std::sort(head->keys.begin(), head->keys.end());
110 head->numChildren++;
111 return;
112 } else if (key == head->keys[0]) {
113 return;
114 } else if (key < head->keys[0]) {
115 head = head->children[0];
116 } else if (key > head->keys[0]) {
117 head = head->children[1];
118 }
119 } else if (head->numChildren == 3) { // case for 3-node
120 if (head->children[0] == nullptr && head->children[1] == nullptr &&
121 head->children[2] == nullptr) {
122 head->keys.push_back(key);
123 std::sort(head->keys.begin(), head->keys.end());
124 head->numChildren++;
125 return;
126 } else if (key == head->keys[0] || key == head->keys[1]) {
127 return;
128 } else if (key < head->keys[0]) {
129 head = head->children[0];
130 } else if (key > head->keys[0] && key < head->keys[1]) {
131 head = head->children[1];
132 } else if (key > head->keys[1]) {
133 head = head->children[2];
134 }
135 } else { // case for 4-node
136 std::shared_ptr<node> parent_node = parent[head];
137 if (parent_node == nullptr) {
138 if (head->numChildren == 2 || head->numChildren == 3) {
139 std::shared_ptr<node> saved_root = head;
140 std::vector<T> passed_keys = {saved_root->keys[1]};
141 root = std::make_shared<node>(passed_keys, null_children, 2);
142 passed_keys = {saved_root->keys[0]};
143 root->children[0] = std::make_shared<node>(passed_keys, null_children, 2);
144 root->children[0]->index = 0;
145 parent[root->children[0]] = root;
146 passed_keys = {saved_root->keys[2]};
147 root->children[1] = std::make_shared<node>(passed_keys, null_children, 2);
148 root->children[1]->index = 1;
149 parent[root->children[1]] = root;
150 head = root;
151 } else {
152 std::shared_ptr<node> saved_root = head;
153 std::vector<T> passed_keys = {saved_root->keys[1]};
154 root = std::make_shared<node>(passed_keys, null_children, 2);
155 passed_keys = {saved_root->keys[0]};
156 root->children[0] = std::make_shared<node>(passed_keys, null_children, 2);
157 parent[root->children[0]] = root;
158 passed_keys = {saved_root->keys[2]};
159 root->children[1] = std::make_shared<node>(passed_keys, null_children, 2);
160 parent[root->children[1]] = root;
161 root->children[0]->children[0] = saved_root->children[0];
162 parent[root->children[0]->children[0]] = root->children[0];
163 root->children[0]->children[1] = saved_root->children[1];
164 parent[root->children[0]->children[1]] = root->children[0];
165 root->children[1]->children[0] = saved_root->children[2];
166 parent[root->children[1]->children[0]] = root->children[1];
167 root->children[1]->children[1] = saved_root->children[3];
168 parent[root->children[1]->children[1]] = root->children[1];
169 head = root;
170 }
171 } else if (parent_node->numChildren == 2) {
172 int curr_index = head->index;
173 std::vector<T> saved_keys = head->keys;
174 parent_node->keys.push_back(saved_keys[1]);
175 parent_node->numChildren++;
176 std::sort(parent_node->keys.begin(), parent_node->keys.end());
177 if (curr_index == 0) {
178 parent_node->children[curr_index + 2] =
179 parent_node->children[curr_index + 1];
180 }
181 std::vector<T> passed_keys = {saved_keys[0]};
182 parent_node->children[curr_index] =
183 std::make_shared<node>(passed_keys, null_children, 2);
184 parent[parent_node->children[curr_index]] = parent_node;
185 parent_node->children[curr_index]->index = curr_index;
186 passed_keys = {saved_keys[2]};
187 parent_node->children[curr_index + 1] =
188 std::make_shared<node>(passed_keys, null_children, 2);
189 parent[parent_node->children[curr_index + 1]] = parent_node;
190 parent_node->children[curr_index + 1]->index = curr_index + 1;
191 head = parent_node;
192 } else if (parent_node->numChildren == 3) {
193 int curr_index = head->index;
194 std::vector<T> saved_keys = head->keys;
195 parent_node->keys.push_back(saved_keys[1]);
196 parent_node->numChildren++;
197 std::sort(parent_node->keys.begin(), parent_node->keys.end());
198 if (curr_index == 0) {
199 parent_node->children[curr_index + 3] =
200 parent_node->children[curr_index + 2];
201 parent_node->children[curr_index + 2] =
202 parent_node->children[curr_index + 1];
203 } else if (curr_index == 1) {
204 parent_node->children[curr_index + 2] =
205 parent_node->children[curr_index + 1];
206 }
207 std::vector<T> passed_keys = {saved_keys[0]};
208 parent_node->children[curr_index] =
209 std::make_shared<node>(passed_keys, null_children, 2);
210 parent_node->children[curr_index]->index = curr_index;
211 parent[parent_node->children[curr_index]] = parent_node;
212 passed_keys = {saved_keys[2]};
213 parent_node->children[curr_index + 1] =
214 std::make_shared<node>(passed_keys, null_children, 2);
215 parent[parent_node->children[curr_index + 1]] = parent_node;
216 parent_node->children[curr_index + 1]->index = curr_index + 1;
217 if (key == parent_node->keys[0] || key == parent_node->keys[1] ||
218 key == parent_node->keys[2]) {
219 return;
220 } else if (key < parent_node->keys[0]) {
221 head = parent_node->children[0];
222 } else if (key > parent_node->keys[0] && key < parent_node->keys[1]) {
223 head = parent_node->children[1];
224 } else if (key > parent_node->keys[1] && key < parent_node->keys[2]) {
225 head = parent_node->children[2];
226 } else if (key > parent_node->keys[2]) {
227 head = parent_node->children[3];
228 }
229 }
230 }
231 }
232 }
233}
234
235template <typename T> inline bool ttf_tree<T>::search(const T& key) const {
236 std::shared_ptr<node> head = root;
237 while (head != nullptr) {
238 if (head->numChildren == 2) { // case for 2-node
239 if (key == head->keys[0] || key == head->keys[1]) {
240 return true;
241 } else if (key < head->keys[0]) {
242 head = head->children[0];
243 } else if (key > head->keys[1]) {
244 head = head->children[1];
245 }
246 } else if (head->numChildren == 3) { // case for 3-node
247 if (key == head->keys[0] || key == head->keys[1]) {
248 return true;
249 } else if (key < head->keys[0]) {
250 head = head->children[0];
251 } else if (key > head->keys[0] && key < head->keys[1]) {
252 head = head->children[1];
253 } else if (key > head->keys[1]) {
254 head = head->children[2];
255 }
256 } else { // case for 4-node
257 if (key == head->keys[0] || key == head->keys[1] || key == head->keys[2]) {
258 return true;
259 } else if (key < head->keys[0]) {
260 head = head->children[0];
261 } else if (key > head->keys[0] && key < head->keys[1]) {
262 head = head->children[1];
263 } else if (key > head->keys[1] && key < head->keys[2]) {
264 head = head->children[2];
265 } else if (key > head->keys[2]) {
266 head = head->children[3];
267 }
268 }
269 }
270 return false;
271}
272
273template <typename T>
274inline std::vector<std::vector<std::vector<T>>> ttf_tree<T>::level_order() const {
275 std::vector<std::vector<std::vector<T>>> level_ordered;
276 std::queue<std::shared_ptr<node>> q;
277 q.push(root);
278 while (!q.empty()) {
279 std::vector<std::vector<T>> line;
280 size_t size = q.size();
281 for (size_t i = 0; i < size; i++) {
282 auto current = q.front();
283 q.pop();
284 line.push_back(current->keys);
285 for (auto x : current->children) {
286 if (x != nullptr) {
287 q.push(x);
288 }
289 }
290 }
291 level_ordered.push_back(line);
292 }
293 return level_ordered;
294}
295
296#endif
ttf_tree(const std::vector< T > &elements={})
default constructor of 234-tree class
Definition 234_tree.h:44
friend std::ostream & operator<<(std::ostream &out, ttf_tree< T > &t)
operator << for ttf_tree class
Definition 234_tree.h:76
bool search(const T &key) const
search function
Definition 234_tree.h:235
void insert(const T &key)
insert function
Definition 234_tree.h:95
std::vector< std::vector< std::vector< T > > > level_order() const
level_order function
Definition 234_tree.h:274