From f54f31cd4f3c12a1a22316b97388d76b8b82a1c1 Mon Sep 17 00:00:00 2001 From: foo290 Date: Mon, 12 Jul 2021 07:53:06 +0530 Subject: [PATCH] docs formatting changed, namespace added --- .../inorder_successor_of_bst.cpp | 298 ++++++++++-------- 1 file changed, 159 insertions(+), 139 deletions(-) diff --git a/operations_on_datastructures/inorder_successor_of_bst.cpp b/operations_on_datastructures/inorder_successor_of_bst.cpp index fe563469f..4b196cfe6 100644 --- a/operations_on_datastructures/inorder_successor_of_bst.cpp +++ b/operations_on_datastructures/inorder_successor_of_bst.cpp @@ -1,27 +1,32 @@ /** * @file - * @brief An implementation for finding [Inorder successor of binary search + * @brief An implementation for finding the [Inorder successor of a binary search * tree](https://www.youtube.com/watch?v=5cPbNCrdotA&t=904s) Inorder successor * of a node is the next node in Inorder traversal of the Binary Tree. Inorder * Successor is NULL for the last node in Inorder traversal. * - * ### Case 1 : The given node has right node/subtree + * ### Case 1 + * + * The given node has right node/subtree + * * In this case the left most deepest node in the right subtree will come * just after the given node as we go to left deep in inorder. * - Go deep to left most node in right subtree. * OR, we can also say in case if BST, find the minimum of the subtree * for a given node. * - * ### Case 2 : The given node does not have a right node/subtree + * ### Case 2 * - * #### Method 1 : Use parent pointer (store the address of parent nodes) + * The given node does not have a right node/subtree + * + * #### Method 1: Use parent pointer (store the address of parent nodes) * If a node does not have right subtree, and we already visited the node * itself, then the next node will be its parent node according to inorder * traversal, and if we are going to parent from left, then the parent would be * unvisited. In other words, go to the nearest ancestor for which given node * would be in left subtree. * - * #### Method 2 : Search from the root node + * #### Method 2: Search from the root node * In case if there is no link to the parent, we need to walk the tree * starting from the root node to the given node, by doing so, we are visiting * every ancestor of the given node. In order successor would be the deepest @@ -31,32 +36,44 @@ * */ #include /// For assert -#include /// For IO Operations +#include /// For IO Operations #include /// For std::vector -namespace binary_search_tree { /** + * @namespace operations_on_datastructures + * @brief Operations on data structures + */ +namespace operations_on_datastructures { + +/** + * @namespace inorder_successor_of_bst + * @brief Functions for the [Inorder successor of a binary search + * tree](https://www.youtube.com/watch?v=5cPbNCrdotA) implementation + */ + namespace inorder_traversal_of_bst { + + /** * @brief A Node structure representing a single node in bst. */ -class Node { - public: - int64_t data; ///< The key/value of the node - Node *left; ///< Pointer to Left child - Node *right; ///< Pointer to right child -}; + class Node { + public: + int64_t data; ///< The key/value of the node + Node *left; ///< Pointer to Left child + Node *right; ///< Pointer to right child + }; /** * @brief Allocates a new node in heap for given data and returns it's pointer. * @param data Data for the node. * @returns A pointer to the newly allocated Node. * */ -Node *makeNode(int64_t data) { - Node *node = new Node(); - node->data = data; ///< setting data for node - node->left = nullptr; ///< setting left child as null - node->right = nullptr; ///< setting right child as null - return node; -} + Node *makeNode(int64_t data) { + Node *node = new Node(); + node->data = data; ///< setting data for node + node->left = nullptr; ///< setting left child as null + node->right = nullptr; ///< setting right child as null + return node; + } /** * @brief Inserts the given data in BST while maintaining the properties of BST. @@ -64,16 +81,16 @@ Node *makeNode(int64_t data) { * @param data Data to be inserted. * @returns Node* Pointer to the root node. * */ -Node *Insert(Node *root, int64_t data) { - if (root == nullptr) { - root = makeNode(data); - } else if (data <= root->data) { - root->left = Insert(root->left, data); - } else { - root->right = Insert(root->right, data); - } - return root; -} + Node *Insert(Node *root, int64_t data) { + if (root == nullptr) { + root = makeNode(data); + } else if (data <= root->data) { + root->left = Insert(root->left, data); + } else { + root->right = Insert(root->right, data); + } + return root; + } /** * @brief Searches the given data in BST and returns the pointer to the node @@ -82,34 +99,65 @@ Node *Insert(Node *root, int64_t data) { * @param data Data to be Searched. * @returns Node* pointer to the found node * */ -Node *getNode(Node *root, int64_t data) { - if (root == nullptr) { - return nullptr; - } else if (root->data == data) { - return root; - } else if (data > root->data) { - /// recursive call - return getNode(root->right, data); - } else { - /// recursive call - return getNode(root->left, data); - } -} + Node *getNode(Node *root, int64_t data) { + if (root == nullptr) { + return nullptr; + } else if (root->data == data) { + return root; + } else if (data > root->data) { + /// recursive call + return getNode(root->right, data); + } else { + /// recursive call + return getNode(root->left, data); + } + } /** * @brief Finds and return the minimum node in BST. * @param root A pointer to root node. * @returns Node* Pointer to the found node * */ -Node *findMinNode(Node *root) { - if (root == nullptr) { - return root; - } - while (root->left != nullptr) { - root = root->left; - } - return root; -} + Node *findMinNode(Node *root) { + if (root == nullptr) { + return root; + } + while (root->left != nullptr) { + root = root->left; + } + return root; + } + +/** + * @brief Prints the BST in inorder traversal using recursion. + * @param root A pointer to the root node of the BST. + * @returns void + * */ + void printInorder(Node *root) { + if (root == nullptr) { + return; + } + + printInorder(root->left); /// recursive call to left subtree + std::cout << root->data << " "; + printInorder(root->right); /// recursive call to right subtree + } + +/** + * @brief This function is used in test cases to quickly create BST containing + * large data instead of hard coding it in code. For a given root, this will add + * all the nodes containing data passes in data vector. + * @param root Pointer to the root node. + * @param data A vector containing integer values which are suppose to be + * inserted as nodes in BST. + * @returns Node pointer to the root node. + * */ + Node *makeBST(Node *root, const std::vector &data) { + for (int64_t values : data) { + root = Insert(root, values); + } + return root; + } /** * @brief Search from the root node as we need to walk the tree starting from @@ -122,69 +170,41 @@ Node *findMinNode(Node *root) { * successor. * @returns Node pointer to the inorder successor node. * */ -Node *getInorderSuccessor(Node *root, int64_t data) { - Node *current = getNode(root, data); - if (current == nullptr) - return nullptr; + Node *getInorderSuccessor(Node *root, int64_t data) { + Node *current = getNode(root, data); + if (current == nullptr) { + return nullptr; + } - // Case - 1 - if (current->right != nullptr) { - return findMinNode(current->right); - } - // case - 2 - else { - Node *successor = nullptr; - Node *ancestor = root; + // Case - 1 + if (current->right != nullptr) { + return findMinNode(current->right); + } + // case - 2 + else { + Node *successor = nullptr; + Node *ancestor = root; - while (ancestor != current && ancestor != nullptr) { - // This means my current node is in left of the root node - if (current->data < ancestor->data) { - successor = ancestor; - ancestor = ancestor->left; // keep going left - } else { - ancestor = ancestor->right; + while (ancestor != current && ancestor != nullptr) { + // This means my current node is in left of the root node + if (current->data < ancestor->data) { + successor = ancestor; + ancestor = ancestor->left; // keep going left + } else { + ancestor = ancestor->right; + } + } + return successor; // Nodes with maximum vales will not have a successor } } - return successor; // Nodes with maximum vales will not have a successor - } -} - -/** - * @brief Prints the BST in inorder traversal using recursion. - * @param root A pointer to the root node of the BST. - * @returns void - * */ -void printInorder(Node *root) { - if (root == nullptr) - return; - - printInorder(root->left); /// recursive call to left subtree - std::cout << root->data << " "; - printInorder(root->right); /// recursive call to right subtree -} - -/** - * @brief This function is used in test cases to quickly create BST containing - * large data instead of hard coding it in code. For a given root, this will add - * all the nodes containing data passes in data vector. - * @param root Pointer to the root node. - * @param data A vector containing integer values which are suppose to be - * inserted as nodes in BST. - * @returns Node pointer to the root node. - * */ -Node *makeBST(Node *root, const std::vector &data) { - for (int64_t values : data) { - root = Insert(root, values); - } - return root; -} -} // namespace binary_search_tree +} // namespace inorder_traversal_of_bst +} // namespace operations_on_datastructures /** * @brief class encapsulating the necessary test cases */ class TestCases { - private: +private: /** * @brief A function to print given message on console. * @tparam T Type of the given message. @@ -196,7 +216,7 @@ class TestCases { std::cout << "[TESTS] : ---> " << msg << std::endl; } - public: +public: /** * @brief Executes test cases * @returns void @@ -218,8 +238,8 @@ class TestCases { * @returns void * */ void testCase_1() { - const binary_search_tree::Node *expectedOutput = - nullptr; ///< Expected output of this test + const operations_on_datastructures::inorder_traversal_of_bst::Node *expectedOutput = + nullptr; ///< Expected output of this test log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); log("This is test case 1 : "); @@ -227,21 +247,21 @@ class TestCases { log(" EDGE CASE : Printing inorder successor for last node in the " "BST, Output will be nullptr."); - binary_search_tree::Node *root = nullptr; + operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr; std::vector node_data{ - 20, 3, 5, 6, 2, 23, 45, 78, 21}; ///< Data to make nodes in BST + 20, 3, 5, 6, 2, 23, 45, 78, 21}; ///< Data to make nodes in BST - root = binary_search_tree::makeBST(root, + root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(root, node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; - binary_search_tree::printInorder( - root); ///< Printing inorder to cross-verify. + operations_on_datastructures::inorder_traversal_of_bst::printInorder( + root); ///< Printing inorder to cross-verify. std::cout << std::endl; - binary_search_tree::Node *inorderSuccessor = - binary_search_tree::getInorderSuccessor( - root, 78); ///< The inorder successor node for given data + operations_on_datastructures::inorder_traversal_of_bst::Node *inorderSuccessor = + operations_on_datastructures::inorder_traversal_of_bst::getInorderSuccessor( + root, 78); ///< The inorder successor node for given data log("Checking assert expression..."); assert(inorderSuccessor == expectedOutput); @@ -265,21 +285,21 @@ class TestCases { log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); log("This is test case 2 : "); - binary_search_tree::Node *root = nullptr; + operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr; std::vector node_data{ - 20, 3, 5, 6, 2, 23, 45, 78, 21}; ///< Data to make nodes in BST + 20, 3, 5, 6, 2, 23, 45, 78, 21}; ///< Data to make nodes in BST - root = binary_search_tree::makeBST(root, + root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(root, node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; - binary_search_tree::printInorder( - root); ///< Printing inorder to cross-verify. + operations_on_datastructures::inorder_traversal_of_bst::printInorder( + root); ///< Printing inorder to cross-verify. std::cout << std::endl; - binary_search_tree::Node *inorderSuccessor = - binary_search_tree::getInorderSuccessor( - root, 20); ///< The inorder successor node for given data + operations_on_datastructures::inorder_traversal_of_bst::Node *inorderSuccessor = + operations_on_datastructures::inorder_traversal_of_bst::getInorderSuccessor( + root, 20); ///< The inorder successor node for given data log("Checking assert expression..."); assert(inorderSuccessor->data == expectedOutput); @@ -303,22 +323,22 @@ class TestCases { log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); log("This is test case 3 : "); - binary_search_tree::Node *root = nullptr; + operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr; std::vector node_data{ - 89, 67, 32, 56, 90, 123, 120, - 110, 115, 6, 78, 7, 10}; ///< Data to make nodes in BST + 89, 67, 32, 56, 90, 123, 120, + 110, 115, 6, 78, 7, 10}; ///< Data to make nodes in BST - root = binary_search_tree::makeBST(root, + root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(root, node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; - binary_search_tree::printInorder( - root); ///< Printing inorder to cross-verify. + operations_on_datastructures::inorder_traversal_of_bst::printInorder( + root); ///< Printing inorder to cross-verify. std::cout << std::endl; - binary_search_tree::Node *inorderSuccessor = - binary_search_tree::getInorderSuccessor( - root, 90); ///< The inorder successor node for given data + operations_on_datastructures::inorder_traversal_of_bst::Node *inorderSuccessor = + operations_on_datastructures::inorder_traversal_of_bst::getInorderSuccessor( + root, 90); ///< The inorder successor node for given data log("Checking assert expression..."); assert(inorderSuccessor->data == expectedOutput); @@ -350,18 +370,18 @@ static void test() { int main(int argc, char *argv[]) { test(); /// run self-test implementations - binary_search_tree::Node *root = nullptr; ///< root node of the bst + operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr; ///< root node of the bst std::vector node_data{3, 4, 5, 89, 1, 2}; ///< Data to add nodes in BST int64_t targetElement = 4; ///< An element to find inorder successor for. - root = binary_search_tree::makeBST(root, node_data); ///< Making BST + root = operations_on_datastructures::inorder_traversal_of_bst::makeBST(root, node_data); ///< Making BST - binary_search_tree::Node *inorderSuccessor = - binary_search_tree::getInorderSuccessor(root, targetElement); + operations_on_datastructures::inorder_traversal_of_bst::Node *inorderSuccessor = + operations_on_datastructures::inorder_traversal_of_bst::getInorderSuccessor(root, targetElement); std::cout << "In-order sequence is : "; - binary_search_tree::printInorder(root); + operations_on_datastructures::inorder_traversal_of_bst::printInorder(root); std::cout << std::endl; if (inorderSuccessor == nullptr) {