AlgoPlus v0.1.0
Loading...
Searching...
No Matches
tree.h
1#ifndef TREE_H
2#define 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#endif
14
19template <typename T> class tree {
20 private:
21 struct node {
22 T info;
23 std::shared_ptr<node> right;
24 std::shared_ptr<node> left;
25 node(T info) : info(info), left(nullptr), right(nullptr) {}
26 };
27
28 int64_t _size{};
29 std::shared_ptr<node> root;
30
31 public:
37 inline explicit tree(std::vector<std::pair<std::string, T>> v = {}) noexcept : root(nullptr) {
38 if (!v.empty()) {
39 for (std::pair<std::string, T>& x : v) {
40 this->insert(x.first, x.second);
41 }
42 }
43 }
44
50 inline void insert(std::string direction, T info) {
51 std::shared_ptr<node> nn = std::make_shared<node>(info);
52 if (!root) {
53 _size++;
54 root = nn;
55 return;
56 }
57 int64_t i = 0;
58 std::shared_ptr<node> head = root;
59 while (head && i < direction.size() - 1) {
60 if (direction[i] == 'r') {
61 head = head->right;
62 } else {
63 head = head->left;
64 }
65 i++;
66 }
67 if (head && direction[i] == 'r') {
68 head->right = nn;
69 } else if (head && direction[i] == 'l') {
70 head->left = nn;
71 }
72 _size++;
73 }
74
81 inline bool search(T key) {
82 std::queue<std::shared_ptr<node>> q;
83 q.push(root);
84 while (!q.empty()) {
85 int64_t size = q.size();
86 for (int64_t i = 0; i < size; ++i) {
87 std::shared_ptr<node> current = q.front();
88 q.pop();
89 if (current->info == key) {
90 return true;
91 }
92 if (current->right) {
93 q.push(current->right);
94 }
95 if (current->left) {
96 q.push(current->left);
97 }
98 }
99 }
100 return false;
101 }
102
103 class Iterator;
104
105 inline Iterator begin() {
106 std::vector<T> ino = this->inorder();
107 return Iterator(0, ino);
108 }
109
110 inline Iterator end() {
111 std::vector<T> ino = this->inorder();
112 return Iterator(ino.size(), ino);
113 }
114
119 inline std::vector<T> inorder() {
120 std::vector<T> ino;
121 _inorder([&](std::shared_ptr<node> callbacked) { ino.push_back(callbacked->info); }, root);
122 return ino;
123 }
124
129 inline std::vector<T> postorder() {
130 std::vector<T> path;
131 _postorder([&](std::shared_ptr<node> callbacked) { path.push_back(callbacked->info); },
132 root);
133 return path;
134 }
135
140 inline std::vector<T> preorder() {
141 std::vector<T> path;
142 _preorder([&](std::shared_ptr<node> callbacked) { path.push_back(callbacked->info); },
143 root);
144 return path;
145 }
146
151 inline std::vector<std::vector<T>> level_order() {
152 std::vector<std::vector<T>> path;
153 std::queue<std::shared_ptr<node>> q;
154 q.push(root);
155 while (!q.empty()) {
156 size_t size = q.size();
157 std::vector<T> level;
158 for (size_t i = 0; i < size; i++) {
159 std::shared_ptr<node> current = q.front();
160 q.pop();
161 level.push_back(current->info);
162 if (current->left) {
163 q.push(current->left);
164 }
165 if (current->right) {
166 q.push(current->right);
167 }
168 }
169 path.push_back(level);
170 }
171 return path;
172 }
173
177 inline friend std::ostream& operator<<(std::ostream& out, tree<T>& t) {
178 std::vector<T> order = t.inorder();
179 for (int i = 0; i < order.size(); i++) {
180 if (i != order.size() - 1) {
181 out << order[i] << ", ";
182 } else {
183 out << order[i] << '\n';
184 }
185 }
186 return out;
187 }
188
193#ifdef TREE_VISUALIZATION_H
194 inline void visualize() {
195 std::string _generated = generate_visualization();
196 tree_visualization::visualize(_generated);
197 }
198#endif
199
200 private:
201 void _inorder(std::function<void(std::shared_ptr<node>)> callback, std::shared_ptr<node> root) {
202 if (root) {
203 _inorder(callback, root->left);
204 callback(root);
205 _inorder(callback, root->right);
206 }
207 }
208
209 void _preorder(std::function<void(std::shared_ptr<node>)> callback,
210 std::shared_ptr<node> root) {
211 if (root) {
212 callback(root);
213 _preorder(callback, root->left);
214 _preorder(callback, root->righ);
215 }
216 }
217
218 void _postorder(std::function<void(std::shared_ptr<node>)> callback,
219 std::shared_ptr<node> root) {
220 if (root) {
221 _postorder(callback, root->right);
222 callback(root);
223 _postorder(callback, root->left);
224 }
225 }
226
227 std::string generate_visualization() {
228 std::string _generate = _inorder_gen(root);
229 return _generate;
230 }
231
232 std::string _inorder_gen(std::shared_ptr<node> root) {
233 std::string _s;
234 if (std::is_same_v<T, char> || std::is_same_v<T, std::string>) {
235 if (root->left) {
236 _s += root->info;
237 _s += "->";
238 _s += root->left->info;
239 _s += "\n";
240 _s += _inorder_gen(root->left);
241 }
242 if (root->right) {
243 _s += root->info;
244 _s += "->";
245 _s += root->right->info;
246 _s += "\n";
247 _s += _inorder_gen(root->right);
248 }
249 } else {
250 if (root->left) {
251 _s += std::to_string(root->info) + "->" + std::to_string(root->left->info) + "\n" +
252 _inorder_gen(root->left);
253 }
254 if (root->right) {
255 _s += std::to_string(root->info) + "->" + std::to_string(root->right->info) + "\n" +
256 _inorder_gen(root->right);
257 }
258 }
259 return _s;
260 }
261};
262
263template <typename T> class tree<T>::Iterator {
264 private:
265 std::vector<T> elements;
266 int64_t index;
267
268 public:
274 explicit Iterator(const int64_t& index, std::vector<T>& els) noexcept
275 : index(index), elements(els) {}
276
283 Iterator& operator=(int64_t index) {
284 this->index = index;
285 return *(this);
286 }
287
294 if (this->index < elements.size()) {
295 this->index++;
296 }
297 return *(this);
298 }
299
306 Iterator it = *this;
307 ++*(this);
308 return it;
309 }
310
317 if (this->index > 0) {
318 this->index--;
319 }
320 return *(this);
321 }
322
329 Iterator it = *this;
330 --*(this);
331 return it;
332 }
333
341 bool operator!=(const Iterator& it) { return index != it.index; }
342
348 T operator*() { return elements[index]; }
349};
350
351#endif
bool operator!=(const Iterator &it)
operator != for type Iterator
Definition tree.h:341
Iterator(const int64_t &index, std::vector< T > &els) noexcept
Construct a new Iterator object.
Definition tree.h:274
Iterator & operator=(int64_t index)
= operator for Iterator type
Definition tree.h:283
Iterator operator--(int)
operator – for type Iterator
Definition tree.h:328
Iterator & operator--()
operator – for type Iterator
Definition tree.h:316
Iterator & operator++()
operator ++ for type Iterator
Definition tree.h:293
T operator*()
operator * for type Iterator
Definition tree.h:348
Iterator operator++(int)
operator ++ for type Iterator
Definition tree.h:305
std::vector< T > postorder()
postorder function
Definition tree.h:129
std::vector< std::vector< T > > level_order()
level order function
Definition tree.h:151
std::vector< T > inorder()
inorder traversal
Definition tree.h:119
std::vector< T > preorder()
preorder function
Definition tree.h:140
friend std::ostream & operator<<(std::ostream &out, tree< T > &t)
operator << for bst class
Definition tree.h:177
bool search(T key)
search function
Definition tree.h:81
tree(std::vector< std::pair< std::string, T > > v={}) noexcept
constructor for tree class
Definition tree.h:37
void insert(std::string direction, T info)
insert function
Definition tree.h:50