TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
binary_search_tree2.cpp
Go to the documentation of this file.
1
8#include <cassert>
9#include <functional>
10#include <iostream>
11#include <memory>
12#include <vector>
13
19template <class T>
21 private:
25 struct bst_node {
27 std::unique_ptr<bst_node> left;
28 std::unique_ptr<bst_node> right;
35 explicit bst_node(T _value) {
36 value = _value;
37 left = nullptr;
38 right = nullptr;
39 }
40 };
41
42 std::unique_ptr<bst_node> root_;
43 std::size_t size_ = 0;
53 bool find_max(std::unique_ptr<bst_node>& node, T& ret_value) {
54 if (!node) {
55 return false;
56 } else if (!node->right) {
57 ret_value = node->value;
58 return true;
59 }
60 return find_max(node->right, ret_value);
61 }
62
71 bool find_min(std::unique_ptr<bst_node>& node, T& ret_value) {
72 if (!node) {
73 return false;
74 } else if (!node->left) {
75 ret_value = node->value;
76 return true;
77 }
78
79 return find_min(node->left, ret_value);
80 }
81
90 bool insert(std::unique_ptr<bst_node>& node, T new_value) {
91 if (root_ == node && !root_) {
92 root_ = std::unique_ptr<bst_node>(new bst_node(new_value));
93 return true;
94 }
95
96 if (new_value < node->value) {
97 if (!node->left) {
98 node->left = std::unique_ptr<bst_node>(new bst_node(new_value));
99 return true;
100 } else {
101 return insert(node->left, new_value);
102 }
103 } else if (new_value > node->value) {
104 if (!node->right) {
105 node->right =
106 std::unique_ptr<bst_node>(new bst_node(new_value));
107 return true;
108 } else {
109 return insert(node->right, new_value);
110 }
111 } else {
112 return false;
113 }
114 }
115
125 bool remove(std::unique_ptr<bst_node>& parent,
126 std::unique_ptr<bst_node>& node, T rm_value) {
127 if (!node) {
128 return false;
129 }
130
131 if (node->value == rm_value) {
132 if (node->left && node->right) {
133 T successor_node_value{};
134 find_max(node->left, successor_node_value);
135 remove(root_, root_, successor_node_value);
136 node->value = successor_node_value;
137 return true;
138 } else if (node->left || node->right) {
139 std::unique_ptr<bst_node>& non_null =
140 (node->left ? node->left : node->right);
141
142 if (node == root_) {
143 root_ = std::move(non_null);
144 } else if (rm_value < parent->value) {
145 parent->left = std::move(non_null);
146 } else {
147 parent->right = std::move(non_null);
148 }
149
150 return true;
151 } else {
152 if (node == root_) {
153 root_.reset(nullptr);
154 } else if (rm_value < parent->value) {
155 parent->left.reset(nullptr);
156 } else {
157 parent->right.reset(nullptr);
158 }
159
160 return true;
161 }
162 } else if (rm_value < node->value) {
163 return remove(node, node->left, rm_value);
164 } else {
165 return remove(node, node->right, rm_value);
166 }
167 }
168
177 bool contains(std::unique_ptr<bst_node>& node, T value) {
178 if (!node) {
179 return false;
180 }
181
182 if (value < node->value) {
183 return contains(node->left, value);
184 } else if (value > node->value) {
185 return contains(node->right, value);
186 } else {
187 return true;
188 }
189 }
190
197 void traverse_inorder(std::function<void(T)> callback,
198 std::unique_ptr<bst_node>& node) {
199 if (!node) {
200 return;
201 }
202
203 traverse_inorder(callback, node->left);
204 callback(node->value);
205 traverse_inorder(callback, node->right);
206 }
207
214 void traverse_preorder(std::function<void(T)> callback,
215 std::unique_ptr<bst_node>& node) {
216 if (!node) {
217 return;
218 }
219
220 callback(node->value);
221 traverse_preorder(callback, node->left);
222 traverse_preorder(callback, node->right);
223 }
224
231 void traverse_postorder(std::function<void(T)> callback,
232 std::unique_ptr<bst_node>& node) {
233 if (!node) {
234 return;
235 }
236
237 traverse_postorder(callback, node->left);
238 traverse_postorder(callback, node->right);
239 callback(node->value);
240 }
241
242 public:
248 root_ = nullptr;
249 size_ = 0;
250 }
251
259 bool insert(T new_value) {
260 bool result = insert(root_, new_value);
261 if (result) {
262 size_++;
263 }
264 return result;
265 }
266
274 bool remove(T rm_value) {
275 bool result = remove(root_, root_, rm_value);
276 if (result) {
277 size_--;
278 }
279 return result;
280 }
281
289 bool contains(T value) { return contains(root_, value); }
290
298 bool find_min(T& ret_value) { return find_min(root_, ret_value); }
299
307 bool find_max(T& ret_value) { return find_max(root_, ret_value); }
308
314 std::size_t size() { return size_; }
315
321 std::vector<T> get_elements_inorder() {
322 std::vector<T> result;
323 traverse_inorder([&](T node_value) { result.push_back(node_value); },
324 root_);
325 return result;
326 }
327
333 std::vector<T> get_elements_preorder() {
334 std::vector<T> result;
335 traverse_preorder([&](T node_value) { result.push_back(node_value); },
336 root_);
337 return result;
338 }
339
345 std::vector<T> get_elements_postorder() {
346 std::vector<T> result;
347 traverse_postorder([&](T node_value) { result.push_back(node_value); },
348 root_);
349 return result;
350 }
351};
352
358static void test_insert() {
359 std::cout << "Testing BST insert...";
360
362 bool res = tree.insert(5);
363 int min = -1, max = -1;
364 assert(res);
365 assert(tree.find_max(max));
366 assert(tree.find_min(min));
367 assert(max == 5);
368 assert(min == 5);
369 assert(tree.size() == 1);
370
371 tree.insert(4);
372 tree.insert(3);
373 tree.insert(6);
374 assert(tree.find_max(max));
375 assert(tree.find_min(min));
376 assert(max == 6);
377 assert(min == 3);
378 assert(tree.size() == 4);
379
380 bool fail_res = tree.insert(4);
381 assert(!fail_res);
382 assert(tree.size() == 4);
383
384 std::cout << "ok" << std::endl;
385}
386
392static void test_remove() {
393 std::cout << "Testing BST remove...";
394
396 tree.insert(5);
397 tree.insert(4);
398 tree.insert(3);
399 tree.insert(6);
400
401 bool res = tree.remove(5);
402 int min = -1, max = -1;
403 assert(res);
404 assert(tree.find_max(max));
405 assert(tree.find_min(min));
406 assert(max == 6);
407 assert(min == 3);
408 assert(tree.size() == 3);
409 assert(tree.contains(5) == false);
410
411 tree.remove(4);
412 tree.remove(3);
413 tree.remove(6);
414 assert(tree.size() == 0);
415 assert(tree.contains(6) == false);
416
417 bool fail_res = tree.remove(5);
418 assert(!fail_res);
419 assert(tree.size() == 0);
420
421 std::cout << "ok" << std::endl;
422}
423
429static void test_contains() {
430 std::cout << "Testing BST contains...";
431
433 tree.insert(5);
434 tree.insert(4);
435 tree.insert(3);
436 tree.insert(6);
437
438 assert(tree.contains(5));
439 assert(tree.contains(4));
440 assert(tree.contains(3));
441 assert(tree.contains(6));
442 assert(!tree.contains(999));
443
444 std::cout << "ok" << std::endl;
445}
446
452static void test_find_min() {
453 std::cout << "Testing BST find_min...";
454
455 int min = 0;
457 assert(!tree.find_min(min));
458
459 tree.insert(5);
460 tree.insert(4);
461 tree.insert(3);
462 tree.insert(6);
463
464 assert(tree.find_min(min));
465 assert(min == 3);
466
467 std::cout << "ok" << std::endl;
468}
469
475static void test_find_max() {
476 std::cout << "Testing BST find_max...";
477
478 int max = 0;
480 assert(!tree.find_max(max));
481
482 tree.insert(5);
483 tree.insert(4);
484 tree.insert(3);
485 tree.insert(6);
486
487 assert(tree.find_max(max));
488 assert(max == 6);
489
490 std::cout << "ok" << std::endl;
491}
492
499 std::cout << "Testing BST get_elements_inorder...";
500
502 tree.insert(5);
503 tree.insert(4);
504 tree.insert(3);
505 tree.insert(6);
506
507 std::vector<int> expected = {3, 4, 5, 6};
508 std::vector<int> actual = tree.get_elements_inorder();
509 assert(actual == expected);
510
511 std::cout << "ok" << std::endl;
512}
513
520 std::cout << "Testing BST get_elements_preorder...";
521
523 tree.insert(5);
524 tree.insert(4);
525 tree.insert(3);
526 tree.insert(6);
527
528 std::vector<int> expected = {5, 4, 3, 6};
529 std::vector<int> actual = tree.get_elements_preorder();
530 assert(actual == expected);
531
532 std::cout << "ok" << std::endl;
533}
534
541 std::cout << "Testing BST get_elements_postorder...";
542
544 tree.insert(5);
545 tree.insert(4);
546 tree.insert(3);
547 tree.insert(6);
548
549 std::vector<int> expected = {3, 4, 6, 5};
550 std::vector<int> actual = tree.get_elements_postorder();
551 assert(actual == expected);
552
553 std::cout << "ok" << std::endl;
554}
555
556int main() {
557 test_insert();
558 test_remove();
565}
static void test_get_elements_inorder()
Function for testing get_elements_inorder().
static void test_contains()
Function for testing contains().
static void test_insert()
Function for testing insert().
static void test_get_elements_postorder()
Function for testing get_elements_postorder().
static void test_find_max()
Function for testing find_max().
static void test_get_elements_preorder()
Function for testing get_elements_preorder().
static void test_remove()
Function for testing remove().
static void test_find_min()
Function for testing find_min().
The Binary Search Tree class.
std::vector< T > get_elements_inorder()
Get all values of the BST in in-order order.
void traverse_inorder(std::function< void(T)> callback, std::unique_ptr< bst_node > &node)
Recursive function to traverse the tree in in-order order.
bool find_max(T &ret_value)
Find the largest value in the BST.
std::size_t size()
Get the number of values in the BST.
std::vector< T > get_elements_preorder()
Get all values of the BST in pre-order order.
std::vector< T > get_elements_postorder()
Get all values of the BST in post-order order.
bool contains(T value)
Check if a value is in the BST.
bool find_max(std::unique_ptr< bst_node > &node, T &ret_value)
Recursive function to find the maximum value in the BST.
bool insert(T new_value)
Insert a new value into the BST.
void traverse_postorder(std::function< void(T)> callback, std::unique_ptr< bst_node > &node)
Recursive function to traverse the tree in post-order order.
bool remove(T rm_value)
Remove a specified value from the BST.
bool insert(std::unique_ptr< bst_node > &node, T new_value)
Recursive function to insert a value into the BST.
std::unique_ptr< bst_node > root_
bool contains(std::unique_ptr< bst_node > &node, T value)
Recursive function to check if a value is in the BST.
binary_search_tree()
Construct a new Binary Search Tree object.
void traverse_preorder(std::function< void(T)> callback, std::unique_ptr< bst_node > &node)
Recursive function to traverse the tree in pre-order order.
bool find_min(T &ret_value)
Find the smallest value in the BST.
bool remove(std::unique_ptr< bst_node > &parent, std::unique_ptr< bst_node > &node, T rm_value)
Recursive function to remove a value from the BST.
bool find_min(std::unique_ptr< bst_node > &node, T &ret_value)
Recursive function to find the minimum value in the BST.
int main()
Main function.
A struct to represent a node in the Binary Search Tree.
std::unique_ptr< bst_node > right
std::unique_ptr< bst_node > left