Merge branch 'ds-ops' of github.com:foo290/C-Plus-Plus into ds-ops

This commit is contained in:
foo290
2021-07-13 07:25:48 +05:30

View File

@@ -1,13 +1,11 @@
/**
* @file
* @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.
* @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 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.
@@ -15,9 +13,7 @@
* 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: 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
@@ -50,30 +46,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.
/**
* @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.
@@ -81,16 +77,16 @@ namespace operations_on_datastructures {
* @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
@@ -99,49 +95,49 @@ namespace operations_on_datastructures {
* @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;
}
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
@@ -152,12 +148,12 @@ namespace operations_on_datastructures {
* inserted as nodes in BST.
* @returns Node pointer to the root node.
* */
Node *makeBST(Node *root, const std::vector<int64_t> &data) {
for (int64_t values : data) {
root = Insert(root, values);
}
return root;
}
Node *makeBST(Node *root, const std::vector<int64_t> &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
@@ -170,33 +166,33 @@ namespace operations_on_datastructures {
* 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;
}
}
return successor; // Nodes with maximum vales will not have a successor
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
}
}
} // namespace inorder_traversal_of_bst
} // namespace operations_on_datastructures
@@ -204,7 +200,7 @@ 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.
@@ -216,7 +212,7 @@ private:
std::cout << "[TESTS] : ---> " << msg << std::endl;
}
public:
public:
/**
* @brief Executes test cases
* @returns void
@@ -238,8 +234,8 @@ public:
* @returns void
* */
void testCase_1() {
const operations_on_datastructures::inorder_traversal_of_bst::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 : ");
@@ -247,21 +243,24 @@ public:
log(" EDGE CASE : Printing inorder successor for last node in the "
"BST, Output will be nullptr.");
operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr;
operations_on_datastructures::inorder_traversal_of_bst::Node *root =
nullptr;
std::vector<int64_t> 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
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
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);
@@ -285,21 +284,24 @@ public:
log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
log("This is test case 2 : ");
operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr;
operations_on_datastructures::inorder_traversal_of_bst::Node *root =
nullptr;
std::vector<int64_t> 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
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
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);
@@ -323,22 +325,25 @@ public:
log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
log("This is test case 3 : ");
operations_on_datastructures::inorder_traversal_of_bst::Node *root = nullptr;
operations_on_datastructures::inorder_traversal_of_bst::Node *root =
nullptr;
std::vector<int64_t> 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
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
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);
@@ -368,17 +373,20 @@ static void test() {
* @returns 0 on exit
*/
int main(int argc, char *argv[]) {
test(); /// run self-test implementations
test(); // run self-test implementations
operations_on_datastructures::inorder_traversal_of_bst::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<int64_t> 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 = operations_on_datastructures::inorder_traversal_of_bst::makeBST(
root, node_data); ///< Making BST
operations_on_datastructures::inorder_traversal_of_bst::Node *inorderSuccessor =
operations_on_datastructures::inorder_traversal_of_bst::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 : ";
operations_on_datastructures::inorder_traversal_of_bst::printInorder(root);