AlgoPlus v0.1.0
Loading...
Searching...
No Matches
bst.h
1#ifndef BST_H
2#define BST_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 <memory>
11#include <queue>
12#include <string>
13#include <type_traits>
14#include <vector>
15#endif
16
20template <typename T> class bst {
21 public:
27 inline explicit bst(std::vector<T> _elements = {}) noexcept : root(nullptr) {
28 if (!_elements.empty()) {
29 for (T& x : _elements) {
30 this->insert(x);
31 }
32 }
33 }
34
39 inline explicit bst(const bst& b) : root(b.root), _size(b._size) {}
40
46 inline bst& operator=(const bst& b) {
47 root = b.root;
48 _size = b._size;
49 return *this;
50 }
51
52 inline ~bst() noexcept { root = nullptr; }
53
57 inline void clear() {
58 root = nullptr;
59 _size = 0;
60 }
61
66 inline void insert(T key) {
67 root = _insert(root, key);
68 _size++;
69 }
70
76 inline bool search(T key) { return _search(root, key); }
77
82 inline void remove(T key) { root = _remove(root, key); }
83
84 class Iterator;
85
91 inline Iterator begin() {
92 std::vector<T> ino = this->inorder();
93 return Iterator(0, ino);
94 }
95
101 inline Iterator end() {
102 std::vector<T> ino = this->inorder();
103 return Iterator(ino.size(), ino);
104 }
105
111 inline size_t size() { return _size; }
112
117 inline std::vector<T> inorder() {
118 std::vector<T> path;
119 _inorder([&](std::shared_ptr<node> callbacked) { path.push_back(callbacked->info); }, root);
120 return path;
121 }
122
127 inline std::vector<T> preorder() {
128 std::vector<T> path;
129 _preorder([&](std::shared_ptr<node> callbacked) { path.push_back(callbacked->info); },
130 root);
131 return path;
132 }
133
138 inline std::vector<T> postorder() {
139 std::vector<T> path;
140 _postorder([&](std::shared_ptr<node> callbacked) { path.push_back(callbacked->info); },
141 root);
142 return path;
143 }
144
149 inline std::vector<std::vector<T>> level_order() {
150 std::vector<std::vector<T>> path;
151 std::queue<std::shared_ptr<node>> q;
152 q.push(root);
153 while (!q.empty()) {
154 size_t size = q.size();
155 std::vector<T> level;
156 for (size_t i = 0; i < size; i++) {
157 std::shared_ptr<node> current = q.front();
158 q.pop();
159 level.push_back(current->info);
160 if (current->left) {
161 q.push(current->left);
162 }
163 if (current->right) {
164 q.push(current->right);
165 }
166 }
167 path.push_back(level);
168 }
169 return path;
170 }
171
176#ifdef TREE_VISUALIZATION_H
177 inline void visualize() {
178 std::string _generated = generate_visualization();
179 tree_visualization::visualize(_generated);
180 }
181#endif
182
186 inline friend std::ostream& operator<<(std::ostream& out, bst<T>& t) {
187 std::vector<T> order = t.inorder();
188 for (int i = 0; i < order.size(); i++) {
189 if (i != order.size() - 1) {
190 out << order[i] << ", ";
191 } else {
192 out << order[i] << '\n';
193 }
194 }
195 return out;
196 }
197
198 private:
205 typedef struct node {
206 T info;
207 std::shared_ptr<node> right;
208 std::shared_ptr<node> left;
209 node(T key) : info(key), right(nullptr), left(nullptr) {}
210 } node;
211
212 std::shared_ptr<node> root;
213 size_t _size{};
214
215 std::shared_ptr<node> new_node(T& key) {
216 std::shared_ptr<node> p = std::make_shared<node>(key);
217 return p;
218 }
219
220 std::shared_ptr<node> _insert(std::shared_ptr<node> root, T& key) {
221 if (!root) {
222 return new_node(key);
223 } else {
224 if (root->info < key) {
225 root->right = _insert(root->right, key);
226 } else {
227 root->left = _insert(root->left, key);
228 }
229 }
230 return root;
231 }
232
233 bool _search(std::shared_ptr<node> root, T& key) {
234 while (root) {
235 if (root->info < key) {
236 root = root->right;
237 } else if (root->info > key) {
238 root = root->left;
239 } else {
240 return true;
241 }
242 }
243 return false;
244 }
245
246 std::shared_ptr<node> _remove(std::shared_ptr<node> root, T& key) {
247 if (!root) {
248 return root;
249 }
250
251 if (root->info < key) {
252 root->right = _remove(root->right, key);
253 } else if (root->info > key) {
254 root->left = _remove(root->left, key);
255 } else {
256 if (!root->left && !root->right) {
257 root = nullptr;
258 _size--;
259 } else if (!root->left) {
260 std::shared_ptr<node> temp = root->right;
261 _size--;
262 return temp;
263 } else if (!root->right) {
264 std::shared_ptr<node> temp = root->left;
265 _size--;
266 return temp;
267 } else {
268 std::shared_ptr<node> temp = root->right;
269 while (temp->left) {
270 temp = temp->left;
271 }
272 root->info = temp->info;
273 root->right = _remove(root->right, temp->info);
274 }
275 }
276 return root;
277 }
278
279 void _inorder(std::function<void(std::shared_ptr<node>)> callback, std::shared_ptr<node> root) {
280 if (root) {
281 _inorder(callback, root->left);
282 callback(root);
283 _inorder(callback, root->right);
284 }
285 }
286
287 void _postorder(std::function<void(std::shared_ptr<node>)> callback,
288 std::shared_ptr<node> root) {
289 if (root) {
290 _postorder(callback, root->left);
291 _postorder(callback, root->right);
292 callback(root);
293 }
294 }
295
296 void _preorder(std::function<void(std::shared_ptr<node>)> callback,
297 std::shared_ptr<node> root) {
298 if (root) {
299 callback(root);
300 _preorder(callback, root->left);
301 _preorder(callback, root->right);
302 }
303 }
304
305 std::string generate_visualization() {
306 std::string _generate = _inorder_gen(root);
307 return _generate;
308 }
309
310 std::string _inorder_gen(std::shared_ptr<node> root) {
311 std::string _s;
312 if (std::is_same_v<T, char> || std::is_same_v<T, std::string>) {
313 if (root->left) {
314 _s += root->info;
315 _s += "->";
316 _s += root->left->info;
317 _s += "\n";
318 _s += _inorder_gen(root->left);
319 }
320 if (root->right) {
321 _s += root->info;
322 _s += "->";
323 _s += root->right->info;
324 _s += "\n";
325 _s += _inorder_gen(root->right);
326 }
327 } else {
328 if (root->left) {
329 _s += std::to_string(root->info) + "->" + std::to_string(root->left->info) + "\n" +
330 _inorder_gen(root->left);
331 }
332 if (root->right) {
333 _s += std::to_string(root->info) + "->" + std::to_string(root->right->info) + "\n" +
334 _inorder_gen(root->right);
335 }
336 }
337 return _s;
338 }
339};
340
344template <typename T> class bst<T>::Iterator {
345 private:
346 std::vector<T> elements;
347 int64_t index;
348
349 public:
355 explicit Iterator(const int64_t& index, std::vector<T>& els) noexcept
356 : index(index), elements(els) {}
357
364 Iterator& operator=(int64_t index) {
365 this->index = index;
366 return *(this);
367 }
368
375 if (this->index < elements.size()) {
376 this->index++;
377 }
378 return *(this);
379 }
380
387 Iterator it = *this;
388 ++*(this);
389 return it;
390 }
391
398 if (this->index > 0) {
399 this->index--;
400 }
401 return *(this);
402 }
403
410 Iterator it = *this;
411 --*(this);
412 return it;
413 }
414
422 bool operator!=(const Iterator& it) { return index != it.index; }
423
429 T operator*() { return elements[index]; }
430};
431
432#endif
Iterator class.
Definition bst.h:344
Iterator & operator++()
operator ++ for type Iterator
Definition bst.h:374
bool operator!=(const Iterator &it)
operator != for type Iterator
Definition bst.h:422
Iterator & operator--()
operator – for type Iterator
Definition bst.h:397
Iterator operator--(int)
operator – for type Iterator
Definition bst.h:409
Iterator & operator=(int64_t index)
= operator for Iterator type
Definition bst.h:364
Iterator(const int64_t &index, std::vector< T > &els) noexcept
Construct a new Iterator object.
Definition bst.h:355
T operator*()
operator * for type Iterator
Definition bst.h:429
Iterator operator++(int)
operator ++ for type Iterator
Definition bst.h:386
Class for BST tree.
Definition bst.h:20
friend std::ostream & operator<<(std::ostream &out, bst< T > &t)
visualize function
Definition bst.h:186
bst(std::vector< T > _elements={}) noexcept
Contructor for BST tree class.
Definition bst.h:27
void clear()
clear function
Definition bst.h:57
void remove(T key)
remove function.
Definition bst.h:82
std::vector< T > preorder()
preorder function.
Definition bst.h:127
std::vector< T > postorder()
postorder function.
Definition bst.h:138
Iterator begin()
pointer that points to begin
Definition bst.h:91
bst(const bst &b)
Copy constructor for bst class.
Definition bst.h:39
size_t size()
size function
Definition bst.h:111
bst & operator=(const bst &b)
operator = for bst class
Definition bst.h:46
Iterator end()
pointer that points to end
Definition bst.h:101
std::vector< std::vector< T > > level_order()
level order function
Definition bst.h:149
std::vector< T > inorder()
inorder function.
Definition bst.h:117
bool search(T key)
search function.
Definition bst.h:76
void insert(T key)
insert function.
Definition bst.h:66