diff --git a/algorithms/CPlusPlus/Trees/binary-search-tree.cpp b/algorithms/CPlusPlus/Trees/binary-search-tree.cpp index ea6954c9..6c059e4f 100644 --- a/algorithms/CPlusPlus/Trees/binary-search-tree.cpp +++ b/algorithms/CPlusPlus/Trees/binary-search-tree.cpp @@ -1,51 +1,52 @@ #include #include + //Structure of the Tree struct TreeNode{ - int data; - TreeNode* left; - TreeNode* right; - TreeNode(const int& data): data(data), left(nullptr), right(nullptr){} + int data; + TreeNode* left; + TreeNode* right; + 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) - * - */ + /** + * 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); } + 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) - * - */ + /** + * 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); } + 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); } } @@ -107,7 +108,7 @@ bool perfect_recursive(TreeNode* cur, int depth, int level = 0){ if(cur->left != nullptr && cur->right != nullptr) { return perfect_recursive(cur->left, depth, level+1) && perfect_recursive(cur->right, depth, level+1); } - return false; + return false; } int count_nodes(TreeNode* cur){ @@ -117,7 +118,7 @@ int count_nodes(TreeNode* cur){ */ if(cur != nullptr){ return 1 + count_nodes(cur->left) + count_nodes(cur->right); } - return 0; + return 0; } @@ -129,7 +130,7 @@ int height(TreeNode* cur){ */ if(cur != nullptr){ return 1 + std::max(height(cur->left), height(cur->right)); } - return 0; + return 0; } bool perfect(TreeNode* cur){ @@ -158,83 +159,226 @@ bool isperfect(TreeNode* root){ //if(perfect(root)) { return true; } if(perfect_recursive(root, depth(root) - 1)) { return true; } - return false; + return false; +} + +void leaf_nodes(TreeNode* root) //Print all leafnode in BST +{ + /* * Node which does not have a child is called as LEAF Node. + * Printing the nodes whose left and right pointer are null. + * @params: `root` root/parent node of the tree + */ + if (!root) + return; + + if (root->left==NULL && root->right==NULL) + { + std::cout<data<< " "; + return; + } + + if (root->left) + leaf_nodes(root->left); + + if (root->right) + leaf_nodes(root->right); +} + +TreeNode* f_min(TreeNode* root) //Find Minimum element from root +{ + /** + * Print the minimum value of the tree + * + * @params: `root` root/parent node of the tree + * @return: void + */ + if(root==NULL) + { + std::cout<<"No value present in the tree"<< std::endl; + return NULL; + } + TreeNode* p=root; + while(p->left!=NULL) + { + p=p->left; + } + return p; +} + +TreeNode* f_max(TreeNode* root) //Find Maximum element from root +{ + /** + * Print the maximum value of the tree + * + * @params: `root` root/parent node of the tree + * @return: void + */ + if(root==NULL) + { + std::cout<<"No value present in the tree"<< std::endl; + return NULL; + } + TreeNode* p=root; + while(p->right!=NULL) + { + p=p->right; + } + return p; +} + +TreeNode* bstdelete(TreeNode* root, int x) +{ + TreeNode* m; + if(root==NULL) + { + std::cout<<"NOT FOUND!!"; + return root; + } + if(x < root->data) + { + root->left=bstdelete(root->left,x); + return root; + } + if(x>root->data) + { + root->right=bstdelete(root->right,x); + return root; + } + if(root->left==NULL && root->right==NULL) + { + m=root; + delete m; + return (NULL); + } + else if(root->left==NULL) + { + m=root; + root=root->right; + delete m; + return (root); + } + else if(root->right==NULL) + { + m=root; + root=root->left; + delete m; + return (root); + } + m=f_min(root->right); + root->data=m->data; + root->right=bstdelete(root->right, m->data); + return (root); } 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); - } + /** + * 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); + } } void free(TreeNode* root){ - /* - * Free up the memory in the heap - * - * @params: `root` root/parent node of the tree - */ + /* + * Free up the memory in the heap + * + * @params: `root` root/parent node of the tree + */ - if(root != nullptr){ - free(root->left); - free(root->right); - delete root; - root = nullptr; - } + if(root != nullptr){ + free(root->left); + free(root->right); + delete root; + root = nullptr; + } } int main(){ - TreeNode* root = nullptr; + 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, 2); - - print(root); + 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, 2); + + print(root); - TreeNode* n = find(root, 19); - std::cout << "\nValue of n: " << n->data << std::endl; + TreeNode* n = find(root, 19); + std::cout << "\nValue of n: " << n->data << std::endl; - if(isfull(root)) { std::cout << "The binary tree is FULL" << std::endl; } - else { std::cout << "The binary tree is not FULL" << std::endl; } + if(isfull(root)) { std::cout << "The binary tree is FULL" << std::endl; } + else { std::cout << "The binary tree is not FULL" << std::endl; } - if(isperfect(root)) { std::cout << "The binary tree is PERFECT" << std::endl; } - else { std::cout << "The binary tree is not PERFECT" << std::endl; } + if(isperfect(root)) { std::cout << "The binary tree is PERFECT" << std::endl; } + else { std::cout << "The binary tree is not PERFECT" << std::endl; } - /* - Tree structure - 37 - / \ - 19 51 - / \ / \ - 4 22 42 55 - /\ / - 2 11 20 + std::cout << "Leaf Nodes present in the binary tree are : "; + leaf_nodes(root); + std::cout<< std::endl; + + n = f_max(root); + if(n) + { + std::cout<<"Maximum Value Present in the tree is : "<data<< std::endl; + } - OUTPUT: - 2 4 11 19 20 22 37 42 51 55 - Value of n: 19 - The binary tree is not FULL - The binary tree is not PERFECT - */ - + n=f_min(root); + if(n) + { + std::cout<<"Minimum Value Present in the tree is : "<data<< std::endl; + } - // free the memory - free(root); - return 0; + root = bstdelete(root, 19); + std::cout<<"Binary search Tree after Deletion is : "< +#include #define endl "\n" using namespace std; @@ -49,6 +50,82 @@ void post_order(struct Node* root){ } +/* Pre, In and Post order Traversal of a Binary Tree using Iteration */ +/* Complexity for each Traversal : O(n) */ + + +void NRpreorder(struct Node* root) //Iterative Preorder Traversal +{ + stack s; + while(!s.empty() || root!=NULL) + { + while(root!=NULL) + { + cout<data<<" "; + s.push(root); + root=root->left; + } + root=s.top(); + s.pop(); + root=root->right; + + } +} + + + +void NRinorder(struct Node* root) //Iterative Inorder Traversal +{ + stack s; + while(!s.empty() || root!=NULL) + { + while(root!=NULL) + { + s.push(root); + root=root->left; + } + root=s.top(); + s.pop(); + cout<data<<" "; + root=root->right; + } +} + + +void NRpostorder(struct Node* root) //Iterative Postorder Traversal +{ + stack s1; + stack s2; + while(root!=NULL) + { + s1.push(root); + s2.push(0); + root=root->left; + } + while(!s1.empty()) + { + root=s1.top(); + if(s2.top()==1) + { + s1.pop(); + s2.pop(); + cout<data<<" "; + } + else + { + s2.top()=1; + root=root->right; + while(root!=NULL) + { + s1.push(root); + s2.push(0); + root=root->left; + } + } + } +} + + int main(){ Node* root = new Node(1); root->left = new Node(2); @@ -63,14 +140,28 @@ int main(){ 2 3 / \ \ 4 5 7 - Expected-> pre-order : 1,2,4,5,3,7 - in-order : 4,2,5,1,3,7 - post-order: 4,5,2,7,3,1 + Expected-> From Recursive calls : + pre-order : 1 2 4 5 3 7 + in-order : 4 2 5 1 3 7 + post-order : 4 5 2 7 3 1 + + From Non-Recursive/Iterative calls : + preorder : 1 2 4 5 3 7 + inorder : 4 2 5 1 3 7 + postorder : 4 5 2 7 3 1 */ + // Tree Traversal using recursive calls + cout<<"From Recursive calls : "; cout<