chore(CPlusPlus): add in-order predecessor and successor for bst (#320)
Co-authored-by: Arsenic <54987647+Arsenic-ATG@users.noreply.github.com>pull/322/head
parent
70efa6fbfc
commit
18c60bf2d5
|
@ -64,6 +64,7 @@
|
|||
4. [Depth first Traversal](Trees/pre-in-post-traversal.cpp)
|
||||
5. [Binary Search Tree](Trees/binary-search-tree.cpp)
|
||||
6. [In order morris traversal](Trees/in-order-morris-traversal.cpp)
|
||||
7. [In order Predecessor and Successor](Trees/in-order-predecessor-and-successor.cpp)
|
||||
|
||||
# Maths
|
||||
1. [Kaprekar Number](Maths/Kaprekar-number.cpp)
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
#include <iostream>
|
||||
|
||||
struct TreeNode{
|
||||
TreeNode* left;
|
||||
TreeNode* right;
|
||||
int data;
|
||||
TreeNode(const int& data): data(data), left(nullptr), right(nullptr){}
|
||||
};
|
||||
|
||||
TreeNode* find(TreeNode* root, const int& data){
|
||||
/**
|
||||
* Find the node that contains the given data and
|
||||
* return that node
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
* @params: `data` data to be find in the tree
|
||||
* @return: tree node that contains the data
|
||||
*
|
||||
* Average case Time Complexity: O(log(n))
|
||||
* Worst case Time Complexity: O(n)
|
||||
*
|
||||
*/
|
||||
|
||||
if(root == nullptr) { throw std::runtime_error("Error: find() cannot find the data. The data doesn't exist."); }
|
||||
else if(root->data == data) { return root; }
|
||||
else if(root->data < data) { return find(root->right, data); }
|
||||
else { return find(root->left, data); }
|
||||
}
|
||||
|
||||
void Insert(TreeNode*& root, const int& data){
|
||||
/**
|
||||
* Create and Insert the node in the appropriate place of the tree
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
* @params: `data` data to be inserted in the tree
|
||||
* @return: void
|
||||
*
|
||||
* Average case Time Complexity: O(log(n))
|
||||
* Worst case Time Complexity: O(n)
|
||||
*
|
||||
*/
|
||||
|
||||
if(root == nullptr) { root = new TreeNode(data); }
|
||||
else if(root->data == data) { throw std::runtime_error("The node already exist. Duplicates not allowed"); }
|
||||
else if(root->data < data) { Insert(root->right, data); }
|
||||
else { Insert(root->left, data); }
|
||||
}
|
||||
|
||||
TreeNode* rightmost(TreeNode* node){
|
||||
/**
|
||||
* Find and return the rightmost value of the sub-tree
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
*
|
||||
* @return: value of the node at the rightmost end of the sub tree
|
||||
*/
|
||||
|
||||
if(node->right == nullptr){ return node; }
|
||||
return rightmost(node->right);
|
||||
}
|
||||
|
||||
TreeNode* predecessor(TreeNode* node, const int& data, TreeNode* value){
|
||||
/**
|
||||
* Find and return the previous smallest value to data
|
||||
*
|
||||
* @params: `node` root/parent node of the tree
|
||||
* @params: `data` data to compare with
|
||||
* @params: `value` holds the previous smaller value to data
|
||||
*
|
||||
* @return: previous smallest value to data
|
||||
*/
|
||||
|
||||
if(node->data < data){ return predecessor(node->right, data, node); }
|
||||
else if(node->data > data){ return predecessor(node->left, data, value); }
|
||||
return value;
|
||||
}
|
||||
|
||||
TreeNode* in_order_predecessor(TreeNode* root, const int& data){
|
||||
/**
|
||||
* Find the in-order predecessor of the given data
|
||||
*
|
||||
* @params: `root` root of the tree
|
||||
* @params: `data` data where it's predecessor to be found
|
||||
*
|
||||
* @return: in-order predecessor for the given data
|
||||
*/
|
||||
|
||||
TreeNode* node = find(root, data);
|
||||
if(node->left !=nullptr){ return rightmost(node->left); }
|
||||
return predecessor(root, data, nullptr);
|
||||
}
|
||||
|
||||
TreeNode* leftmost(TreeNode* node){
|
||||
/**
|
||||
* Find and return the leftmost value of the sub-tree
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
*
|
||||
* @return: value of the node at the leftmost end of the sub tree
|
||||
*/
|
||||
|
||||
if(node->left == nullptr){ return node; }
|
||||
return leftmost(node->left);
|
||||
}
|
||||
|
||||
TreeNode* successor(TreeNode* node, const int& data, TreeNode* value){
|
||||
/**
|
||||
* Find and return the next biggest value to data
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
* @params: `data` data to compare with
|
||||
* @params: `value` holds the next biggest value to data
|
||||
*
|
||||
* @return: previous smaller value to data
|
||||
*/
|
||||
|
||||
if(node->data < data){ return successor(node->right, data, value); }
|
||||
else if(node->data > data){ return successor(node->left, data, node); }
|
||||
return value;
|
||||
}
|
||||
|
||||
TreeNode* in_order_successor(TreeNode* root, const int& data){
|
||||
/**
|
||||
* Find the in-order successor of the given data
|
||||
*
|
||||
* @params: `data` data where it's predecessor to be found
|
||||
* @params: `root` root of the tree for the prevSmallerAncester function
|
||||
*
|
||||
* @return: in-order successor for the given data
|
||||
*/
|
||||
|
||||
TreeNode* node = find(root, data);
|
||||
if(node->right !=nullptr){ return leftmost(node->right); }
|
||||
return successor(root, data, nullptr);
|
||||
}
|
||||
|
||||
void print(TreeNode* root){
|
||||
/**
|
||||
* Print the tree in an inorder fashion
|
||||
*
|
||||
* @params: `root` root/parent node of the tree
|
||||
* @return: void
|
||||
*/
|
||||
|
||||
if(root != nullptr){
|
||||
print(root->left);
|
||||
std::cout << root->data << " ";
|
||||
print(root->right);
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
TreeNode* root = nullptr;
|
||||
|
||||
Insert(root, 37);
|
||||
Insert(root, 19);
|
||||
Insert(root, 4);
|
||||
Insert(root, 22);
|
||||
Insert(root, 51);
|
||||
Insert(root, 55);
|
||||
Insert(root, 42);
|
||||
Insert(root, 20);
|
||||
Insert(root, 11);
|
||||
Insert(root, 0);
|
||||
|
||||
print(root);
|
||||
|
||||
/*
|
||||
Tree structure
|
||||
37
|
||||
/ \
|
||||
19 51
|
||||
/ \ / \
|
||||
4 22 42 55
|
||||
/\ /
|
||||
0 11 20
|
||||
|
||||
OUTPUT:
|
||||
0 4 11 19 20 22 37 42 51 55
|
||||
*/
|
||||
|
||||
int value = 4;
|
||||
if(in_order_predecessor(root, value)){
|
||||
std::cout << "\nPredecessor of " << value << " is " << in_order_predecessor(root, value)->data << std::endl;
|
||||
}
|
||||
else{ std::cout << "\nNo predecessor" << std::endl; }
|
||||
|
||||
if(in_order_successor(root, value)){
|
||||
std::cout << "Successor of " << value << " is " << in_order_successor(root, value)->data << std::endl;
|
||||
}
|
||||
else{ std::cout << "No successor" << std::endl; }
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue