From f1b8319824f5cbb2178966b00b429102553f5110 Mon Sep 17 00:00:00 2001 From: foo290 Date: Tue, 13 Jul 2021 07:58:14 +0530 Subject: [PATCH] docs improved --- .../inorder_successor_of_bst.cpp | 269 +++++++++--------- 1 file changed, 135 insertions(+), 134 deletions(-) diff --git a/operations_on_datastructures/inorder_successor_of_bst.cpp b/operations_on_datastructures/inorder_successor_of_bst.cpp index d62230bba..ffbbd9797 100644 --- a/operations_on_datastructures/inorder_successor_of_bst.cpp +++ b/operations_on_datastructures/inorder_successor_of_bst.cpp @@ -4,36 +4,33 @@ * 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. - * + * @details * ### Case 1: The given node has the 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. + * 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. + * 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 * * #### 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. + * * If a node does not have the 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 - * * 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 - * node in this path for which given node is in left subtree. + * * In case if there is no link from a child node to the parent node, we need to walk down 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 node in this path for which given node is in left subtree. * * @author [Nitin Sharma](https://github.com/foo290) * */ -#include /// For assert -#include /// For IO Operations -#include /// For std::vector +#include /// for assert +#include /// for IO Operations +#include /// for std::vector /** * @namespace operations_on_datastructures @@ -46,30 +43,30 @@ namespace operations_on_datastructures { * @brief Functions for the [Inorder successor of a binary search * tree](https://www.youtube.com/watch?v=5cPbNCrdotA) implementation */ -namespace inorder_traversal_of_bst { + 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. @@ -77,16 +74,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 @@ -95,49 +92,51 @@ 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; /// Node found! + } else if (data > root->data) { + /// Traverse right subtree recursively as the given data is greater than the data in root node, + /// data must be present in right subtree. + return getNode(root->right, data); + } else { + /// Traverse left subtree recursively as the given data is less than the data in root node, + /// data must be present in left subtree. + 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; - } + 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 -} + 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 @@ -148,51 +147,53 @@ void printInorder(Node *root) { * 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; -} + 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 + * @brief Inorder successor of a node is the next node in inorder traversal of the Binary Tree. + * This function takes the root node and the data of the node for which we have to find the inorder successor, and + * returns the inorder successor node. + * @details Search from the root node as 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 node in this path * for which given node is in left subtree. Time complexity O(h) - * * @param root A pointer to the root node of the BST * @param data The data (or the data of node) for which we have to find inorder * 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 - } -} } // namespace inorder_traversal_of_bst } // namespace operations_on_datastructures @@ -200,7 +201,7 @@ Node *getInorderSuccessor(Node *root, int64_t data) { * @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. @@ -212,7 +213,7 @@ class TestCases { std::cout << "[TESTS] : ---> " << msg << std::endl; } - public: +public: /** * @brief Executes test cases * @returns void @@ -235,7 +236,7 @@ class TestCases { * */ void testCase_1() { const operations_on_datastructures::inorder_traversal_of_bst::Node - *expectedOutput = nullptr; ///< Expected output of this test + *expectedOutput = nullptr; ///< Expected output of this test log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); log("This is test case 1 : "); @@ -244,23 +245,23 @@ class TestCases { "BST, Output will be nullptr."); operations_on_datastructures::inorder_traversal_of_bst::Node *root = - nullptr; + 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST( - root, - node_data); ///< Adding nodes to BST + root, + node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; operations_on_datastructures::inorder_traversal_of_bst::printInorder( - root); ///< Printing inorder to cross-verify. + root); ///< Printing inorder to cross-verify. std::cout << std::endl; 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 + *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); @@ -285,23 +286,23 @@ class TestCases { log("This is test case 2 : "); operations_on_datastructures::inorder_traversal_of_bst::Node *root = - nullptr; + 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST( - root, - node_data); ///< Adding nodes to BST + root, + node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; operations_on_datastructures::inorder_traversal_of_bst::printInorder( - root); ///< Printing inorder to cross-verify. + root); ///< Printing inorder to cross-verify. std::cout << std::endl; 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 + *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); @@ -326,24 +327,24 @@ class TestCases { log("This is test case 3 : "); operations_on_datastructures::inorder_traversal_of_bst::Node *root = - nullptr; + 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST( - root, - node_data); ///< Adding nodes to BST + root, + node_data); ///< Adding nodes to BST std::cout << "Inorder sequence is : "; operations_on_datastructures::inorder_traversal_of_bst::printInorder( - root); ///< Printing inorder to cross-verify. + root); ///< Printing inorder to cross-verify. std::cout << std::endl; 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 + *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); @@ -376,17 +377,17 @@ int main(int argc, char *argv[]) { test(); // run self-test implementations operations_on_datastructures::inorder_traversal_of_bst::Node *root = - nullptr; ///< root node of the bst + 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST( - root, node_data); ///< Making BST + root, node_data); ///< Making BST operations_on_datastructures::inorder_traversal_of_bst::Node - *inorderSuccessor = operations_on_datastructures:: - inorder_traversal_of_bst::getInorderSuccessor(root, targetElement); + *inorderSuccessor = operations_on_datastructures:: + inorder_traversal_of_bst::getInorderSuccessor(root, targetElement); std::cout << "In-order sequence is : "; operations_on_datastructures::inorder_traversal_of_bst::printInorder(root);