AlgoPlus v0.1.0
Loading...
Searching...
No Matches
interval_tree.h
1#ifndef INTERVAL_TREE_H
2#define INTERVAL_TREE_H
3
4#ifdef ENABLE_TREE_VISUALIZATION
5#include "../../visualization/tree_visual/tree_visualization.h"
6#endif
7
8#ifdef __cplusplus
9#include <functional>
10#include <iostream>
11#include <memory>
12#include <queue>
13#include <vector>
14#endif
15
19template <typename T> class interval_tree {
20 public:
26 inline interval_tree(std::vector<std::pair<T, T>> v = {}) {
27 if (!v.empty()) {
28 for (auto& x : v) {
29 this->insert({x.first, x.second});
30 }
31 }
32 }
33
39 inline explicit interval_tree(const interval_tree& i) : root(i.root), _size(i._size) {}
40
47 root = i.root;
48 _size = i._size;
49 return *this;
50 }
51
52 inline ~interval_tree() { root = nullptr; }
53
57 inline void clear() {
58 root = nullptr;
59 _size = 0;
60 }
61
66 inline void insert(std::pair<T, T> p) {
67 interval i = interval(p);
68 root = _insert(root, i);
69 _size++;
70 }
71
76 inline bool search(std::pair<T, T> p) {
77 if (!root) {
78 return false;
79 }
80 interval i = interval(p);
81 if (this->overlap({root->i->low, root->i->high}, p)) {
82 return true;
83 }
84 return _search(root, i);
85 }
86
91 inline void remove(std::pair<T, T> p) {
92 interval i = interval(p);
93 root = _remove(root, i);
94 }
95
102 inline bool overlap(std::pair<T, T> p1, std::pair<T, T> p2) {
103 interval i1 = interval(p1), i2 = interval(p2);
104 return i1.high >= i2.low && i1.low <= i2.high;
105 }
106
107 class Iterator;
108
114 inline Iterator begin() {
115 std::vector<std::pair<T, T>> ino = this->inorder();
116 return Iterator(0, ino);
117 }
118
124 inline Iterator end() {
125 std::vector<std::pair<T, T>> ino = this->inorder();
126 return Iterator(ino.size(), ino);
127 }
128
134 inline size_t size() { return _size; }
135
140 inline std::vector<std::pair<T, T>> inorder() {
141 std::vector<std::pair<T, T>> path;
142 _inorder(
143 [&](std::shared_ptr<node> callbacked) {
144 path.push_back({callbacked->i->low, callbacked->i->high});
145 },
146 root);
147 return path;
148 }
149
154 inline std::vector<std::pair<T, T>> preorder() {
155 std::vector<std::pair<T, T>> path;
156 _preorder(
157 [&](std::shared_ptr<node> callbacked) {
158 path.push_back({callbacked->i->low, callbacked->i->high});
159 },
160 root);
161 return path;
162 }
163
168 inline std::vector<std::pair<T, T>> postorder() {
169 std::vector<std::pair<T, T>> path;
170 _postorder(
171 [&](std::shared_ptr<node> callbacked) {
172 path.push_back({callbacked->i->low, callbacked->i->high});
173 },
174 root);
175 return path;
176 }
177
182 inline std::vector<std::vector<std::pair<T, T>>> level_order() {
183 std::vector<std::vector<std::pair<T, T>>> path;
184 std::queue<std::shared_ptr<node>> q;
185 q.push(root);
186 while (!q.empty()) {
187 size_t size = q.size();
188 std::vector<std::pair<T, T>> level;
189 for (size_t i = 0; i < size; i++) {
190 std::shared_ptr<node> current = q.front();
191 q.pop();
192 level.push_back({current->i->low, current->i->high});
193 if (current->left) {
194 q.push(current->left);
195 }
196 if (current->right) {
197 q.push(current->right);
198 }
199 }
200 path.push_back(level);
201 }
202 return path;
203 }
204
205#ifdef TREE_VISUALIZATION_H
206 inline void visualize() {
207 std::string _generated = generate_visualization();
208 tree_visualization::visualize(_generated);
209 }
210#endif
211
215 inline friend std::ostream& operator<<(std::ostream& out, interval_tree<T>& t) {
216 std::vector<std::vector<std::pair<T, T>>> order = t.level_order();
217 for (std::vector<std::pair<T, T>>& x : order) {
218 for (size_t i = 0; i < x.size(); i++) {
219 if (i != x.size() - 1) {
220 out << '[' << x[i].first << "," << x[i].second << ']' << ", ";
221 } else {
222 out << '[' << x[i].first << "," << x[i].second << ']' << '\n';
223 }
224 }
225 }
226 return out;
227 }
228
229 private:
235 struct interval {
236 T low;
237 T high;
238 interval(std::pair<T, T> p)
239 : low(std::min(p.first, p.second)), high(std::max(p.first, p.second)) {}
240 };
241
250 struct node {
251 interval* i;
252 int max;
253 std::shared_ptr<node> right;
254 std::shared_ptr<node> left;
255 node(interval n) : i(new interval(n)), max(n.high), right(nullptr), left(nullptr) {}
256 };
257
258 std::shared_ptr<node> root;
259 size_t _size{};
260
261 std::shared_ptr<node> new_node(interval i) {
262 std::shared_ptr<node> p = std::make_shared<node>(i);
263 return p;
264 }
265
269 std::shared_ptr<node> _insert(std::shared_ptr<node> root, interval i) {
270 if (!root) {
271 return new_node(i);
272 }
273 T l = root->i->low;
274 if (i.low < l) {
275 root->left = _insert(root->left, i);
276 } else {
277 root->right = _insert(root->right, i);
278 }
279 if (root->max < i.high) {
280 root->max = i.high;
281 }
282 return root;
283 }
284
288 bool _search(std::shared_ptr<node> root, interval i) {
289 if (!root) {
290 return false;
291 }
292 if (root->left && root->left->max >= i.low) {
293 return _search(root->left, i);
294 }
295 return _search(root->right, i);
296 }
297
301 std::shared_ptr<node> _remove(std::shared_ptr<node> root, interval i) {
302 if (!root) {
303 return nullptr;
304 }
305 std::shared_ptr<node> p = root;
306 while (p) {
307 if (p->i->low > i.low) {
308 p = p->left;
309 } else if (p->i->low < i.low) {
310 p = p->right;
311 } else {
312 if (!p->right && !p->left) {
313 _size--;
314 return nullptr;
315 } else if (p->right && !p->left) {
316 std::shared_ptr<node> temp = root->right;
317 _size--;
318 return temp;
319 } else if (p->left && !p->right) {
320 std::shared_ptr<node> temp = p->left;
321 _size--;
322 return temp;
323 } else {
324 std::shared_ptr<node> temp = root;
325 while (temp && temp->left) {
326 temp = temp->left;
327 }
328 p->i = temp->i;
329 p->max = temp->max;
330 p->right = _remove(p->right, *temp->i);
331 }
332 }
333 }
334 return root;
335 }
336
337 void _inorder(std::function<void(std::shared_ptr<node>)> callback, std::shared_ptr<node> root) {
338 if (root) {
339 _inorder(callback, root->left);
340 callback(root);
341 _inorder(callback, root->right);
342 }
343 }
344
345 void _postorder(std::function<void(std::shared_ptr<node>)> callback,
346 std::shared_ptr<node> root) {
347 if (root) {
348 _postorder(callback, root->left);
349 _postorder(callback, root->right);
350 callback(root);
351 }
352 }
353
354 void _preorder(std::function<void(std::shared_ptr<node>)> callback,
355 std::shared_ptr<node> root) {
356 if (root) {
357 callback(root);
358 _preorder(callback, root->left);
359 _preorder(callback, root->right);
360 }
361 }
362
363 std::string generate_visualization() {
364 std::string _generate = _inorder_gen(root);
365 return _generate;
366 }
367
368 std::string _inorder_gen(std::shared_ptr<node> root) {
369 std::string _s;
370 if (std::is_same_v<T, char> || std::is_same_v<T, std::string>) {
371 if (root->left) {
372 _s += '"';
373 _s += root->i->low;
374 _s += ',';
375 _s += root->i->high;
376 _s += '"';
377 _s += "->";
378 _s += '"';
379 _s += root->left->i->low;
380 _s += ',';
381 _s += root->left->i->high;
382 _s += '"';
383 _s += "\n";
384 _s += _inorder_gen(root->left);
385 }
386 if (root->right) {
387 _s += '"';
388 _s += root->i->low;
389 _s += ',';
390 _s += root->i->high;
391 _s += '"';
392 _s += "->";
393 _s += '"';
394 _s += root->right->i->low;
395 _s += ',';
396 _s += root->right->i->high;
397 _s += '"';
398 _s += "\n";
399 _s += _inorder_gen(root->right);
400 }
401 } else {
402 if (root->left) {
403 _s += '"';
404 _s += std::to_string(root->i->low);
405 _s += ',';
406 _s += std::to_string(root->i->high);
407 _s += '"';
408 _s += "->";
409 _s += '"';
410 _s += std::to_string(root->left->i->low);
411 _s += ',';
412 _s += std::to_string(root->left->i->high);
413 _s += '"';
414 _s += "\n";
415 _s += _inorder_gen(root->left);
416 }
417 if (root->right) {
418 _s += '"';
419 _s += std::to_string(root->i->low);
420 _s += ',';
421 _s += std::to_string(root->i->high);
422 _s += '"';
423 _s += "->";
424 _s += '"';
425 _s += std::to_string(root->right->i->low);
426 _s += ',';
427 _s += std::to_string(root->right->i->high);
428 _s += '"';
429 _s += "\n";
430 _s += _inorder_gen(root->right);
431 }
432 }
433 return _s;
434 }
435};
436
440template <typename T> class interval_tree<T>::Iterator {
441 private:
442 std::vector<std::pair<T, T>> elements;
443 int64_t index;
444
445 public:
451 explicit Iterator(const int64_t& index, std::vector<std::pair<T, T>>& els) noexcept
452 : index(index), elements(els) {}
453
460 Iterator& operator=(int64_t index) {
461 this->index = index;
462 return *(this);
463 }
464
471 if (this->index < elements.size()) {
472 this->index++;
473 }
474 return *(this);
475 }
476
483 Iterator it = *this;
484 ++*(this);
485 return it;
486 }
487
494 if (this->index > 0) {
495 this->index--;
496 }
497 return *(this);
498 }
499
506 Iterator it = *this;
507 --*(this);
508 return it;
509 }
510
518 bool operator!=(const Iterator& it) { return index != it.index; }
519
525 std::pair<T, T> operator*() { return {elements[index].first, elements[index].second}; }
526};
527
528#endif
Iterator class.
Definition interval_tree.h:440
bool operator!=(const Iterator &it)
operator != for type Iterator
Definition interval_tree.h:518
Iterator operator--(int)
operator – for type Iterator
Definition interval_tree.h:505
std::pair< T, T > operator*()
operator * for type Iterator
Definition interval_tree.h:525
Iterator(const int64_t &index, std::vector< std::pair< T, T > > &els) noexcept
Construct a new Iterator object.
Definition interval_tree.h:451
Iterator & operator=(int64_t index)
= operator for Iterator type
Definition interval_tree.h:460
Iterator operator++(int)
operator ++ for type Iterator
Definition interval_tree.h:482
Iterator & operator++()
operator ++ for type Iterator
Definition interval_tree.h:470
Iterator & operator--()
operator – for type Iterator
Definition interval_tree.h:493
interval tree class
Definition interval_tree.h:19
Iterator end()
pointer that points to end
Definition interval_tree.h:124
std::vector< std::vector< std::pair< T, T > > > level_order()
level order function.
Definition interval_tree.h:182
interval_tree(std::vector< std::pair< T, T > > v={})
Construct a new interval tree object.
Definition interval_tree.h:26
bool overlap(std::pair< T, T > p1, std::pair< T, T > p2)
overlap function.
Definition interval_tree.h:102
void clear()
clear function
Definition interval_tree.h:57
bool search(std::pair< T, T > p)
search function.
Definition interval_tree.h:76
std::vector< std::pair< T, T > > inorder()
inorder function.
Definition interval_tree.h:140
void remove(std::pair< T, T > p)
remove function.
Definition interval_tree.h:91
friend std::ostream & operator<<(std::ostream &out, interval_tree< T > &t)
operator << for interval tree class
Definition interval_tree.h:215
void insert(std::pair< T, T > p)
insert function.
Definition interval_tree.h:66
Iterator begin()
pointer that points to begin
Definition interval_tree.h:114
interval_tree & operator=(const interval_tree &i)
operator = for interval tree class
Definition interval_tree.h:46
std::vector< std::pair< T, T > > preorder()
preorder function.
Definition interval_tree.h:154
size_t size()
size function
Definition interval_tree.h:134
std::vector< std::pair< T, T > > postorder()
postorder function.
Definition interval_tree.h:168
interval_tree(const interval_tree &i)
Copy constructor for interval tree class.
Definition interval_tree.h:39