diff --git a/algorithms/Binary Trees/BSTtoMinHeap.cpp b/algorithms/Binary Trees/BSTtoMinHeap.cpp new file mode 100644 index 00000000..797d80f2 --- /dev/null +++ b/algorithms/Binary Trees/BSTtoMinHeap.cpp @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +using namespace std; + +// Data structure to store a binary tree node +struct Node +{ + int data; + Node* left = nullptr, *right = nullptr; + + Node() {} + Node(int data): data(data) {} +}; + +// Recursive function to insert a key into a BST +Node* insert(Node* root, int key) +{ + // if the root is null, create a new node and return it + if (root == nullptr) { + return new Node(key); + } + + // if the given key is less than the root node, recur for the left subtree + if (key < root->data) { + root->left = insert(root->left, key); + } + + // if the given key is more than the root node, recur for the right subtree + else { + root->right = insert(root->right, key); + } + + return root; +} + +// Helper function to perform level order traversal on a binary tree +void printLevelOrderTraversal(Node* root) +{ + // base case: empty tree + if (root == nullptr) { + return; + } + + queue q; + q.push(root); + + while (!q.empty()) + { + int n = q.size(); + while (n--) + { + Node* front = q.front(); + q.pop(); + + cout << front->data << ' '; + + if (front->left) { + q.push(front->left); + } + + if (front->right) { + q.push(front->right); + } + } + + cout << endl; + } +} + +// Function to perform inorder traversal on a given binary tree and +// enqueue all nodes (in encountered order) +void inorder(Node* root, queue &keys) +{ + if (root == nullptr) { + return; + } + + inorder(root->left, keys); + keys.push(root->data); + inorder(root->right, keys); +} + +// Function to perform preorder traversal on a given binary tree. +// Assign each encountered node with the next key from the queue +void preorder(Node* root, queue &keys) +{ + // base case: empty tree + if (root == nullptr) { + return; + } + + // replace the root's key value with the next key from the queue + root->data = keys.front(); + keys.pop(); + + // process left subtree + preorder(root->left, keys); + + // process right subtree + preorder(root->right, keys); +} + +// Function to convert a BST into a min-heap +void convert(Node* root) +{ + // base case + if (root == nullptr) { + return; + } + + // maintain a queue to store inorder traversal on the tree + queue keys; + + // fill the queue in an inorder fashion + inorder(root, keys); + + // traverse tree in preorder fashion, and for each encountered node, + // dequeue a key and assign it to the node + preorder(root, keys); +} + +int main() +{ + vector keys = { 5, 3, 2, 4, 8, 6, 10 }; + + /* Construct the following BST + 5 + / \ + / \ + 3 8 + / \ / \ + / \ / \ + 2 4 6 10 + */ + + Node* root = nullptr; + for (int key: keys) { + root = insert(root, key); + } + + convert(root); + printLevelOrderTraversal(root); + + return 0; +} \ No newline at end of file diff --git a/algorithms/Binary Trees/DeleteNodeBST.cpp b/algorithms/Binary Trees/DeleteNodeBST.cpp new file mode 100644 index 00000000..4a577488 --- /dev/null +++ b/algorithms/Binary Trees/DeleteNodeBST.cpp @@ -0,0 +1,126 @@ +#include +using namespace std; + +// Data structure to store a BST node +struct Node +{ + int data; + Node* left = nullptr, *right = nullptr; + + Node() {} + Node(int data): data(data) {} +}; + +// Function to perform inorder traversal on the BST +void inorder(Node* root) +{ + if (root == nullptr) { + return; + } + + inorder(root->left); + cout << root->data << " "; + inorder(root->right); +} + +// Helper function to find the maximum value node in the subtree rooted at `ptr` +Node* findMaximumKey(Node* ptr) +{ + while (ptr->right != nullptr) { + ptr = ptr->right; + } + return ptr; +} + +// Recursive function to insert a key into a BST +Node* insert(Node* root, int key) +{ + // if the root is null, create a new node and return it + if (root == nullptr) { + return new Node(key); + } + + // if the given key is less than the root node, recur for the left subtree + if (key < root->data) { + root->left = insert(root->left, key); + } + + // if the given key is more than the root node, recur for the right subtree + else { + root->right = insert(root->right, key); + } + + return root; +} + +// Function to delete a node from a BST. Note that root is passed by +// reference to the function +void deleteNode(Node* &root, int key) +{ + // base case: the key is not found in the tree + if (root == nullptr) { + return; + } + + // if the given key is less than the root node, recur for the left subtree + if (key < root->data) { + deleteNode(root->left, key); + } + + // if the given key is more than the root node, recur for the right subtree + else if (key > root->data) { + deleteNode(root->right, key); + } + + // key found + else { + // Case 1: node to be deleted has no children (it is a leaf node) + if (root->left == nullptr && root->right == nullptr) + { + // deallocate the memory and update root to null + delete root; + root = nullptr; + } + + // Case 2: node to be deleted has two children + else if (root->left && root->right) + { + // find its inorder predecessor node + Node* predecessor = findMaximumKey(root->left); + + // copy value of the predecessor to the current node + root->data = predecessor->data; + + // recursively delete the predecessor. Note that the + // predecessor will have at most one child (left child) + deleteNode(root->left, predecessor->data); + } + + // Case 3: node to be deleted has only one child + else { + // choose a child node + Node* child = (root->left)? root->left: root->right; + Node* curr = root; + + root = child; + + // deallocate the memory + delete curr; + } + } +} + +int main() +{ + int keys[] = { 15, 10, 20, 8, 12, 25 }; + + Node* root = nullptr; + for (int key: keys) { + root = insert(root, key); + } + + deleteNode(root, 12); + inorder(root); + + return 0; +} diff --git a/algorithms/Binary Trees/MergeTwoBST.CPP b/algorithms/Binary Trees/MergeTwoBST.CPP new file mode 100644 index 00000000..6e150981 --- /dev/null +++ b/algorithms/Binary Trees/MergeTwoBST.CPP @@ -0,0 +1,82 @@ +#include +using namespace std; + +// Structure of a BST Node +class Node { +public: + int val; + Node* left; + Node* right; +}; + +/* Utility function to create a new Binary Tree Node */ +Node* newNode(int data) +{ + Node* temp = new Node; + temp->val = data; + temp->left = nullptr; + temp->right = nullptr; + return temp; +} + +vector mergeTwoBST(Node* root1, Node* root2) +{ + vector res; + stack s1, s2; + while (root1 || root2 || !s1.empty() || !s2.empty()) { + while (root1) { + s1.push(root1); + root1 = root1->left; + } + while (root2) { + s2.push(root2); + root2 = root2->left; + } + // Step 3 Case 1:- + if (s2.empty() || (!s1.empty() && s1.top()->val <= s2.top()->val)) { + root1 = s1.top(); + s1.pop(); + res.push_back(root1->val); + root1 = root1->right; + } + // Step 3 case 2 :- + else { + root2 = s2.top(); + s2.pop(); + res.push_back(root2->val); + root2 = root2->right; + } + } + return res; +} + +/* Driver program to test above functions */ +int main() +{ + Node *root1 = nullptr, *root2 = nullptr; + + /* Let us create the following tree as first tree + 3 + / \ + 1 5 + */ + root1 = newNode(3); + root1->left = newNode(1); + root1->right = newNode(5); + + /* Let us create the following tree as second tree + 4 + / \ + 2 6 + */ + root2 = newNode(4); + root2->left = newNode(2); + root2->right = newNode(6); + + // Print sorted Nodes of both trees + vector ans = mergeTwoBST(root1, root2); + for (auto it : ans) + cout << it << " "; + return 0; +} +