From 5ecd7e289ac2b07e9fb226d5c85ea505d07f9253 Mon Sep 17 00:00:00 2001 From: Ankith Veldandi <143205588+aveldan@users.noreply.github.com> Date: Thu, 4 Jul 2024 01:07:18 -0400 Subject: [PATCH 1/2] Added level order for all tree --- src/classes/tree/avl_tree.h | 28 ++++++++++++++++++++++++++++ src/classes/tree/bst.h | 28 ++++++++++++++++++++++++++++ src/classes/tree/interval_tree.h | 29 +++++++++++++++++++++++++++++ src/classes/tree/splay_tree.h | 29 +++++++++++++++++++++++++++++ src/classes/tree/tree.h | 28 ++++++++++++++++++++++++++++ tests/tree/avl.cc | 9 +++++++++ tests/tree/bst.cc | 17 +++++++++++++++++ tests/tree/interval_tree.cc | 14 ++++++++++++++ tests/tree/splay_tree.cc | 17 +++++++++++++++++ tests/tree/tree.cc | 18 ++++++++++++++++-- 10 files changed, 215 insertions(+), 2 deletions(-) diff --git a/src/classes/tree/avl_tree.h b/src/classes/tree/avl_tree.h index 23a12485..682816c6 100644 --- a/src/classes/tree/avl_tree.h +++ b/src/classes/tree/avl_tree.h @@ -158,6 +158,34 @@ template class avl_tree { return path; } + /** + *@brief level order function. + *@returns vector, the elements level ordered. + */ + std::vector> levelorder() { + std::vector> path; + std::queue> q; + q.push(root); + while(!q.empty()){ + size_t size = q.size(); + std::vector level; + while(size > 0){ + size -= 1; + std::shared_ptr current = q.front(); + q.pop(); + level.push_back(current->info); + if(current->left){ + q.push(current->left); + } + if(current->right){ + q.push(current->right); + } + } + path.push_back(level); + } + return path; + } + /** *@brief visualize function *@returns .dot file that can be previewed using graphviz in vscode. diff --git a/src/classes/tree/bst.h b/src/classes/tree/bst.h index dda9d9b7..6df5c252 100644 --- a/src/classes/tree/bst.h +++ b/src/classes/tree/bst.h @@ -156,6 +156,34 @@ template class bst { return path; } + /** + * @brief level order function + * @return vector>, the elements level ordered. + */ + std::vector> levelorder() { + std::vector> path; + std::queue> q; + q.push(root); + while(!q.empty()){ + size_t size = q.size(); + std::vector level; + while(size > 0){ + size -= 1; + std::shared_ptr current = q.front(); + q.pop(); + level.push_back(current->info); + if(current->left){ + q.push(current->left); + } + if(current->right){ + q.push(current->right); + } + } + path.push_back(level); + } + return path; + } + /** *@brief visualize function *@returns .dot file that can be previewed using graphviz in vscode. diff --git a/src/classes/tree/interval_tree.h b/src/classes/tree/interval_tree.h index 6841716c..5e899443 100644 --- a/src/classes/tree/interval_tree.h +++ b/src/classes/tree/interval_tree.h @@ -8,6 +8,7 @@ #include #include #include +#include #endif /** @@ -176,6 +177,34 @@ template class interval_tree { return path; } + /** + *@brief level order function. + *@returns vector>, the elements level ordered. + */ + std::vector>> levelorder() { + std::vector>> path; + std::queue> q; + q.push(root); + while(!q.empty()){ + size_t size = q.size(); + std::vector> level; + while(size > 0){ + size -= 1; + std::shared_ptr current = q.front(); + q.pop(); + level.push_back({current->i->low, current->i->high}); + if(current->left){ + q.push(current->left); + } + if(current->right){ + q.push(current->right); + } + } + path.push_back(level); + } + return path; + } + void visualize() { std::string __generated = generate_visualization(); tree_visualization::visualize(__generated); diff --git a/src/classes/tree/splay_tree.h b/src/classes/tree/splay_tree.h index ffac9c4d..4302991e 100644 --- a/src/classes/tree/splay_tree.h +++ b/src/classes/tree/splay_tree.h @@ -8,6 +8,7 @@ #include #include #include +#include #endif /** @@ -168,6 +169,34 @@ template class splay_tree { return path; } + /** + * @brief level order function + * @return vector>, the elements level ordered. + */ + std::vector> levelorder() { + std::vector> path; + std::queue> q; + q.push(root); + while(!q.empty()){ + size_t size = q.size(); + std::vector level; + while(size > 0){ + size -= 1; + std::shared_ptr current = q.front(); + q.pop(); + level.push_back(current->info); + if(current->left){ + q.push(current->left); + } + if(current->right){ + q.push(current->right); + } + } + path.push_back(level); + } + return path; + } + /** *@brief visualize function *@returns .dot file that can be previewed using graphviz in vscode. diff --git a/src/classes/tree/tree.h b/src/classes/tree/tree.h index 3bd6e265..da8cc54e 100644 --- a/src/classes/tree/tree.h +++ b/src/classes/tree/tree.h @@ -151,6 +151,34 @@ class tree{ return path; } + /** + * @brief level order function + * @return vector>: the level order traversal of the tree + */ + std::vector> levelorder() { + std::vector> path; + std::queue> q; + q.push(root); + while(!q.empty()){ + size_t size = q.size(); + std::vector level; + while(size > 0){ + size -= 1; + std::shared_ptr current = q.front(); + q.pop(); + level.push_back(current->info); + if(current->left){ + q.push(current->left); + } + if(current->right){ + q.push(current->right); + } + } + path.push_back(level); + } + return path; + } + private: void __inorder(std::function)> callback, std::shared_ptr root){ diff --git a/tests/tree/avl.cc b/tests/tree/avl.cc index c244864b..b53f5ef2 100644 --- a/tests/tree/avl.cc +++ b/tests/tree/avl.cc @@ -138,4 +138,13 @@ TEST_CASE("testing operator = for avl tree class") { b = a; REQUIRE(a.inorder() == b.inorder()); REQUIRE(a.preorder() == b.preorder()); +} + +TEST_CASE("testing level order in avl tree"){ + avl_tree t; + for(int i=1;i<=10;i++) + t.insert(i); + std::vector> produced = t.levelorder(); + std::vector> sol = {{4}, {2,8}, {1,3,6,9}, {5,7,10}}; + REQUIRE(produced==sol); } \ No newline at end of file diff --git a/tests/tree/bst.cc b/tests/tree/bst.cc index 1c78332f..f90b13fe 100644 --- a/tests/tree/bst.cc +++ b/tests/tree/bst.cc @@ -131,4 +131,21 @@ TEST_CASE("testing operator = for bst class") { b2 = b; REQUIRE(b.inorder() == b2.inorder()); REQUIRE(b.preorder() == b2.preorder()); +} + +TEST_CASE("testing level order in bst"){ + bst t; + t.insert(5); + t.insert(1); + t.insert(2); + t.insert(3); + t.insert(6); + t.insert(8); + t.insert(7); + t.insert(10); + t.insert(9); + t.insert(4); + std::vector> produced = t.levelorder(); + std::vector> sol = {{5}, {1,6}, {2,8}, {3,7,10}, {4,9}}; + REQUIRE(produced == sol); } \ No newline at end of file diff --git a/tests/tree/interval_tree.cc b/tests/tree/interval_tree.cc index 5d3c173e..5a5e92c2 100644 --- a/tests/tree/interval_tree.cc +++ b/tests/tree/interval_tree.cc @@ -64,4 +64,18 @@ TEST_CASE("testing operator = for interval tree class") { i2 = i; REQUIRE(i.inorder() == i2.inorder()); REQUIRE(i.preorder() == i2.preorder()); +} + +TEST_CASE("testing level order in interval tree"){ + interval_tree t; + t.insert({15,20}); + t.insert({8,13}); + t.insert({1,20}); + t.insert({12,15}); + t.insert({19,30}); + t.insert({17,19}); + t.insert({22,25}); + std::vector>> produced = t.levelorder(); + std::vector>> sol = {{{15,20}}, {{8,13}, {19,30}}, {{1,20}, {12,15}, {17,19}, {22,25}}}; + REQUIRE(produced==sol); } \ No newline at end of file diff --git a/tests/tree/splay_tree.cc b/tests/tree/splay_tree.cc index a55cd086..4147ea34 100644 --- a/tests/tree/splay_tree.cc +++ b/tests/tree/splay_tree.cc @@ -108,4 +108,21 @@ TEST_CASE("testing operator = for splay tree class") { s2 = s; REQUIRE(s.inorder() == s2.inorder()); REQUIRE(s.preorder() == s2.preorder()); +} + +TEST_CASE("testing level order for splay tree"){ + splay_tree t; + t.insert(5); + t.insert(1); + t.insert(2); + t.insert(3); + t.insert(6); + t.insert(8); + t.insert(7); + t.insert(10); + t.insert(9); + t.insert(4); + std::vector> produced = t.levelorder(); + std::vector> sol = {{4}, {3,8}, {2,6,9}, {1,5,7,10}}; + REQUIRE(produced==sol); } \ No newline at end of file diff --git a/tests/tree/tree.cc b/tests/tree/tree.cc index 4002ecec..a451201b 100644 --- a/tests/tree/tree.cc +++ b/tests/tree/tree.cc @@ -35,5 +35,19 @@ TEST_CASE("testing iterators for tree class [TREE]"){ REQUIRE(check == v); } - - +TEST_CASE("testing level order traversal in tree class [TREECLASS]"){ + tree t; + t.insert("", 1); + t.insert("l", 2); + t.insert("r", 3); + t.insert("ll", 4); + t.insert("lr", 5); + t.insert("rl", 6); + t.insert("rr", 7); + t.insert("lll", 8); + t.insert("llr", 9); + t.insert("lrl", 10); + std::vector> produced = t.levelorder(); + std::vector> sol = {{1},{2,3},{4,5,6,7},{8,9,10}}; + REQUIRE(produced == sol); +} \ No newline at end of file From 17165a93a9c4b6369c1c65fc99f1caab1cdd9e48 Mon Sep 17 00:00:00 2001 From: Spiros Maggioros Date: Thu, 4 Jul 2024 11:02:56 +0300 Subject: [PATCH 2/2] Minor changes to syntax --- src/classes/tree/avl_tree.h | 13 ++-- src/classes/tree/bst.h | 13 ++-- src/classes/tree/interval_tree.h | 15 ++-- src/classes/tree/splay_tree.h | 17 +++-- src/classes/tree/tree.h | 118 +++++++++++++++---------------- tests/tree/avl.cc | 4 +- tests/tree/bst.cc | 4 +- tests/tree/interval_tree.cc | 4 +- tests/tree/splay_tree.cc | 4 +- tests/tree/tree.cc | 4 +- 10 files changed, 96 insertions(+), 100 deletions(-) diff --git a/src/classes/tree/avl_tree.h b/src/classes/tree/avl_tree.h index 682816c6..49f7cd53 100644 --- a/src/classes/tree/avl_tree.h +++ b/src/classes/tree/avl_tree.h @@ -160,24 +160,23 @@ template class avl_tree { /** *@brief level order function. - *@returns vector, the elements level ordered. + *@returns vector, the level order traversal of the tree */ - std::vector> levelorder() { + std::vector> level_order() { std::vector> path; std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { size_t size = q.size(); std::vector level; - while(size > 0){ - size -= 1; + for (size_t i = 0; i < size; i++) { std::shared_ptr current = q.front(); q.pop(); level.push_back(current->info); - if(current->left){ + if (current->left) { q.push(current->left); } - if(current->right){ + if (current->right) { q.push(current->right); } } diff --git a/src/classes/tree/bst.h b/src/classes/tree/bst.h index 6df5c252..86e4ca97 100644 --- a/src/classes/tree/bst.h +++ b/src/classes/tree/bst.h @@ -158,24 +158,23 @@ template class bst { /** * @brief level order function - * @return vector>, the elements level ordered. + * @return vector>, the level order traversal of the tree */ - std::vector> levelorder() { + std::vector> level_order() { std::vector> path; std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { size_t size = q.size(); std::vector level; - while(size > 0){ - size -= 1; + for (size_t i = 0; i < size; i++) { std::shared_ptr current = q.front(); q.pop(); level.push_back(current->info); - if(current->left){ + if (current->left) { q.push(current->left); } - if(current->right){ + if (current->right) { q.push(current->right); } } diff --git a/src/classes/tree/interval_tree.h b/src/classes/tree/interval_tree.h index 5e899443..13f988f8 100644 --- a/src/classes/tree/interval_tree.h +++ b/src/classes/tree/interval_tree.h @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #endif /** @@ -179,24 +179,23 @@ template class interval_tree { /** *@brief level order function. - *@returns vector>, the elements level ordered. + *@returns vector>, the level order traversal of the tree */ - std::vector>> levelorder() { + std::vector>> level_order() { std::vector>> path; std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { size_t size = q.size(); std::vector> level; - while(size > 0){ - size -= 1; + for (size_t i = 0; i < size; i++) { std::shared_ptr current = q.front(); q.pop(); level.push_back({current->i->low, current->i->high}); - if(current->left){ + if (current->left) { q.push(current->left); } - if(current->right){ + if (current->right) { q.push(current->right); } } diff --git a/src/classes/tree/splay_tree.h b/src/classes/tree/splay_tree.h index 4302991e..a359dcf5 100644 --- a/src/classes/tree/splay_tree.h +++ b/src/classes/tree/splay_tree.h @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #endif /** @@ -169,26 +169,25 @@ template class splay_tree { return path; } - /** + /** * @brief level order function - * @return vector>, the elements level ordered. + * @return vector>, the level order traversal of the tree */ - std::vector> levelorder() { + std::vector> level_order() { std::vector> path; std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { size_t size = q.size(); std::vector level; - while(size > 0){ - size -= 1; + for (size_t i = 0; i < size; i++) { std::shared_ptr current = q.front(); q.pop(); level.push_back(current->info); - if(current->left){ + if (current->left) { q.push(current->left); } - if(current->right){ + if (current->right) { q.push(current->right); } } diff --git a/src/classes/tree/tree.h b/src/classes/tree/tree.h index da8cc54e..f0ab89ce 100644 --- a/src/classes/tree/tree.h +++ b/src/classes/tree/tree.h @@ -3,37 +3,37 @@ #define TREE_H #ifdef __cplusplus -#include #include +#include #include #endif - /** * @brief tree class * */ -template -class tree{ +template class tree { private: - struct node{ + struct node { T info; std::shared_ptr right; std::shared_ptr left; node(T info) : info(info), left(nullptr), right(nullptr) {} }; - + int64_t __size; std::shared_ptr root; public: /** * @brief constructor for tree class - * @param v: the input vector of pairs(string and T) to avoid doing multiple insertions + * @param v: the input vector of pairs(string and T) to avoid doing multiple + * insertions */ - explicit tree(std::vector > v = {}) noexcept : root(nullptr) { - if(!v.empty()){ - for(std::pair &x : v){ + explicit tree(std::vector> v = {}) noexcept + : root(nullptr) { + if (!v.empty()) { + for (std::pair &x : v) { this->insert(x.first, x.second); } } @@ -44,29 +44,27 @@ class tree{ * @param direction: string, directions for the insertion of value info * @param info: the value of the new node */ - void insert(std::string direction, T info){ + void insert(std::string direction, T info) { std::shared_ptr nn = std::make_shared(info); - if(!root){ + if (!root) { __size++; root = nn; return; } int64_t i = 0; std::shared_ptr head = root; - while(head && i < direction.size() - 1){ - if(direction[i] == 'r'){ - head = head -> right; - } - else{ - head = head -> left; + while (head && i < direction.size() - 1) { + if (direction[i] == 'r') { + head = head->right; + } else { + head = head->left; } i++; } - if(head && direction[i] == 'r'){ - head -> right = nn; - } - else if(head && direction[i] == 'l'){ - head -> left = nn; + if (head && direction[i] == 'r') { + head->right = nn; + } else if (head && direction[i] == 'l') { + head->left = nn; } __size++; } @@ -77,22 +75,22 @@ class tree{ * @return true: if the key exist in the tree * @return false: otherwise */ - bool search(T key){ + bool search(T key) { std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { int64_t size = q.size(); - for(int64_t i = 0; i current = q.front(); q.pop(); - if(current -> info == key){ + if (current->info == key) { return true; } - if(current -> right){ - q.push(current -> right); + if (current->right) { + q.push(current->right); } - if(current -> left){ - q.push(current -> left); + if (current->left) { + q.push(current->left); } } } @@ -101,12 +99,12 @@ class tree{ class Iterator; - Iterator begin(){ + Iterator begin() { std::vector ino = this->inorder(); return Iterator(0, ino); } - Iterator end(){ + Iterator end() { std::vector ino = this->inorder(); return Iterator(ino.size(), ino); } @@ -115,14 +113,16 @@ class tree{ * @brief inorder traversal * @return vector: the inorder traversal of the tree */ - std::vector inorder(){ + std::vector inorder() { std::vector ino; - __inorder([&](std::shared_ptr callbacked){ - ino.push_back(callbacked -> info); - }, root); + __inorder( + [&](std::shared_ptr callbacked) { + ino.push_back(callbacked->info); + }, + root); return ino; } - + /** * @brief postorder function * @return vector: the postorder traversal of the tree @@ -136,7 +136,7 @@ class tree{ root); return path; } - + /** * @brief preorder function * @return vector: the preorder traversal of the tree @@ -155,22 +155,21 @@ class tree{ * @brief level order function * @return vector>: the level order traversal of the tree */ - std::vector> levelorder() { + std::vector> level_order() { std::vector> path; std::queue> q; q.push(root); - while(!q.empty()){ + while (!q.empty()) { size_t size = q.size(); std::vector level; - while(size > 0){ - size -= 1; + for (size_t i = 0; i < size; i++) { std::shared_ptr current = q.front(); q.pop(); level.push_back(current->info); - if(current->left){ + if (current->left) { q.push(current->left); } - if(current->right){ + if (current->right) { q.push(current->right); } } @@ -180,28 +179,30 @@ class tree{ } private: - - void __inorder(std::function)> callback, std::shared_ptr root){ - if(root){ - __inorder(callback, root -> left); + void __inorder(std::function)> callback, + std::shared_ptr root) { + if (root) { + __inorder(callback, root->left); callback(root); - __inorder(callback, root -> right); + __inorder(callback, root->right); } } - void __preorder(std::function)> callback, std::shared_ptr root){ - if(root){ + void __preorder(std::function)> callback, + std::shared_ptr root) { + if (root) { callback(root); - __preorder(callback, root -> left); - __preorder(callback, root -> righ); + __preorder(callback, root->left); + __preorder(callback, root->righ); } } - void __postorder(std::function)> callback, std::shared_ptr root){ - if(root){ - __postorder(callback, root -> right); + void __postorder(std::function)> callback, + std::shared_ptr root) { + if (root) { + __postorder(callback, root->right); callback(root); - __postorder(callback, root -> left); + __postorder(callback, root->left); } } }; @@ -294,5 +295,4 @@ template class tree::Iterator { T operator*() { return elements[index]; } }; - #endif diff --git a/tests/tree/avl.cc b/tests/tree/avl.cc index b53f5ef2..aca36c7d 100644 --- a/tests/tree/avl.cc +++ b/tests/tree/avl.cc @@ -144,7 +144,7 @@ TEST_CASE("testing level order in avl tree"){ avl_tree t; for(int i=1;i<=10;i++) t.insert(i); - std::vector> produced = t.levelorder(); + std::vector> produced = t.level_order(); std::vector> sol = {{4}, {2,8}, {1,3,6,9}, {5,7,10}}; REQUIRE(produced==sol); -} \ No newline at end of file +} diff --git a/tests/tree/bst.cc b/tests/tree/bst.cc index f90b13fe..80d41a78 100644 --- a/tests/tree/bst.cc +++ b/tests/tree/bst.cc @@ -145,7 +145,7 @@ TEST_CASE("testing level order in bst"){ t.insert(10); t.insert(9); t.insert(4); - std::vector> produced = t.levelorder(); + std::vector> produced = t.level_order(); std::vector> sol = {{5}, {1,6}, {2,8}, {3,7,10}, {4,9}}; REQUIRE(produced == sol); -} \ No newline at end of file +} diff --git a/tests/tree/interval_tree.cc b/tests/tree/interval_tree.cc index 5a5e92c2..a1696044 100644 --- a/tests/tree/interval_tree.cc +++ b/tests/tree/interval_tree.cc @@ -75,7 +75,7 @@ TEST_CASE("testing level order in interval tree"){ t.insert({19,30}); t.insert({17,19}); t.insert({22,25}); - std::vector>> produced = t.levelorder(); + std::vector>> produced = t.level_order(); std::vector>> sol = {{{15,20}}, {{8,13}, {19,30}}, {{1,20}, {12,15}, {17,19}, {22,25}}}; REQUIRE(produced==sol); -} \ No newline at end of file +} diff --git a/tests/tree/splay_tree.cc b/tests/tree/splay_tree.cc index 4147ea34..8dbc7742 100644 --- a/tests/tree/splay_tree.cc +++ b/tests/tree/splay_tree.cc @@ -122,7 +122,7 @@ TEST_CASE("testing level order for splay tree"){ t.insert(10); t.insert(9); t.insert(4); - std::vector> produced = t.levelorder(); + std::vector> produced = t.level_order(); std::vector> sol = {{4}, {3,8}, {2,6,9}, {1,5,7,10}}; REQUIRE(produced==sol); -} \ No newline at end of file +} diff --git a/tests/tree/tree.cc b/tests/tree/tree.cc index a451201b..d32ba15f 100644 --- a/tests/tree/tree.cc +++ b/tests/tree/tree.cc @@ -47,7 +47,7 @@ TEST_CASE("testing level order traversal in tree class [TREECLASS]"){ t.insert("lll", 8); t.insert("llr", 9); t.insert("lrl", 10); - std::vector> produced = t.levelorder(); + std::vector> produced = t.level_order(); std::vector> sol = {{1},{2,3},{4,5,6,7},{8,9,10}}; REQUIRE(produced == sol); -} \ No newline at end of file +}