Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update binary_search_tree.cpp #2741

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 129 additions & 108 deletions data_structures/binary_search_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,168 +7,189 @@
* utilize any of the C++ STL features.
*/
#include <iostream>
#include <memory>
#include <vector>
#include <queue>

struct node {
// Node structure representing each element in the binary tree
struct Node {
int val;
node *left;
node *right;
};
std::unique_ptr<Node> left; // Using unique_ptr for automatic memory management
std::unique_ptr<Node> right;

struct Queue {
node *t[100];
int front;
int rear;
Node(int value) : val(value), left(nullptr), right(nullptr) {}
};

Queue queue;

void enqueue(node *n) { queue.t[queue.rear++] = n; }

node *dequeue() { return (queue.t[queue.front++]); }
class BinaryTree {
public:
std::unique_ptr<Node> root; // Root of the binary tree

void Insert(node *n, int x) {
if (x < n->val) {
if (n->left == NULL) {
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->left = temp;
// Insert a value into the tree
void insert(int x) {
if (!root) {
root = std::make_unique<Node>(x); // Create root if it doesn't exist
} else {
Insert(n->left, x);
insertHelper(root.get(), x); // Helper function for recursive insertion
}
} else {
if (n->right == NULL) {
node *temp = new node;
temp->val = x;
temp->left = NULL;
temp->right = NULL;
n->right = temp;
} else {
Insert(n->right, x);
}

// Remove a value from the tree
void remove(int x) {
removeHelper(root, x); // Helper function to manage removal
}

// Breadth-first traversal of the tree
void breadthFirstTraversal() const {
if (!root) return;
std::queue<Node*> q; // Using STL queue for level-order traversal
q.push(root.get());
while (!q.empty()) {
Node* current = q.front();
q.pop();
std::cout << current->val << " "; // Print the current node's value
if (current->left) q.push(current->left.get());
if (current->right) q.push(current->right.get());
}
}
}

int findMaxInLeftST(node *n) {
while (n->right != NULL) {
n = n->right;
// Preorder traversal
void preOrderTraversal() const {
preOrderHelper(root.get());
}
return n->val;
}

void Remove(node *p, node *n, int x) {
if (n->val == x) {
if (n->right == NULL && n->left == NULL) {
if (x < p->val) {
p->right = NULL;
} else {
p->left = NULL;
}
} else if (n->right == NULL) {
if (x < p->val) {
p->right = n->left;
// Inorder traversal
void inOrderTraversal() const {
inOrderHelper(root.get());
}

// Postorder traversal
void postOrderTraversal() const {
postOrderHelper(root.get());
}

private:
// Helper function for insertion
void insertHelper(Node* node, int x) {
if (x < node->val) {
if (!node->left) {
node->left = std::make_unique<Node>(x); // Create left child if it doesn't exist
} else {
p->left = n->left;
insertHelper(node->left.get(), x); // Recur to the left
}
} else if (n->left == NULL) {
if (x < p->val) {
p->right = n->right;
} else {
if (!node->right) {
node->right = std::make_unique<Node>(x); // Create right child if it doesn't exist
} else {
p->left = n->right;
insertHelper(node->right.get(), x); // Recur to the right
}
} else {
int y = findMaxInLeftST(n->left);
n->val = y;
Remove(n, n->right, y);
}
} else if (x < n->val) {
Remove(n, n->left, x);
} else {
Remove(n, n->right, x);
}
}

void BFT(node *n) {
if (n != NULL) {
std::cout << n->val << " ";
enqueue(n->left);
enqueue(n->right);
BFT(dequeue());
// Helper function to find the maximum value in the left subtree
Node* findMaxInLeft(Node* node) {
while (node->right) {
node = node->right.get();
}
return node;
}
}

void Pre(node *n) {
if (n != NULL) {
std::cout << n->val << " ";
Pre(n->left);
Pre(n->right);
// Helper function for removing a node
Node* removeHelper(std::unique_ptr<Node>& node, int x) {
if (!node) return nullptr; // Base case: node not found

if (x < node->val) {
node->left = removeHelper(node->left, x); // Recur left
} else if (x > node->val) {
node->right = removeHelper(node->right, x); // Recur right
} else {
// Node found: handle three cases
if (!node->left) {
return std::move(node->right); // No left child
} else if (!node->right) {
return std::move(node->left); // No right child
} else {
// Node with two children: replace with max value from left subtree
int maxVal = findMaxInLeft(node->left.get())->val;
node->val = maxVal; // Replace value
node->left = removeHelper(node->left, maxVal); // Remove the max value
}
}
return std::move(node); // Return updated node
}
}

void In(node *n) {
if (n != NULL) {
In(n->left);
std::cout << n->val << " ";
In(n->right);
// Preorder traversal helper
void preOrderHelper(Node* node) const {
if (node) {
std::cout << node->val << " "; // Visit node
preOrderHelper(node->left.get()); // Recur left
preOrderHelper(node->right.get()); // Recur right
}
}
}

void Post(node *n) {
if (n != NULL) {
Post(n->left);
Post(n->right);
std::cout << n->val << " ";
// Inorder traversal helper
void inOrderHelper(Node* node) const {
if (node) {
inOrderHelper(node->left.get()); // Recur left
std::cout << node->val << " "; // Visit node
inOrderHelper(node->right.get()); // Recur right
}
}
}

// Postorder traversal helper
void postOrderHelper(Node* node) const {
if (node) {
postOrderHelper(node->left.get()); // Recur left
postOrderHelper(node->right.get()); // Recur right
std::cout << node->val << " "; // Visit node
}
}
};

int main() {
queue.front = 0;
queue.rear = 0;
BinaryTree tree;
int value;
int ch;
node *root = new node;
std::cout << "\nEnter the value of root node :";
std::cout << "\nEnter the value of root node: ";
std::cin >> value;
root->val = value;
root->left = NULL;
root->right = NULL;
tree.insert(value); // Insert the root value

int choice;
do {
std::cout << "\n1. Insert"
<< "\n2. Delete"
<< "\n3. Breadth First"
<< "\n4. Preorder Depth First"
<< "\n5. Inorder Depth First"
<< "\n6. Postorder Depth First";
<< "\n6. Postorder Depth First"
<< "\n0. Exit"
<< "\nEnter Your Choice: ";
std::cin >> choice;

std::cout << "\nEnter Your Choice : ";
std::cin >> ch;
int x;
switch (ch) {
switch (choice) {
case 1:
std::cout << "\nEnter the value to be Inserted : ";
std::cout << "\nEnter the value to be Inserted: ";
std::cin >> x;
Insert(root, x);
tree.insert(x); // Insert value
break;
case 2:
std::cout << "\nEnter the value to be Deleted : ";
std::cout << "\nEnter the value to be Deleted: ";
std::cin >> x;
Remove(root, root, x);
tree.remove(x); // Remove value
break;
case 3:
BFT(root);
tree.breadthFirstTraversal(); // Perform breadth-first traversal
break;
case 4:
Pre(root);
tree.preOrderTraversal(); // Perform preorder traversal
break;
case 5:
In(root);
tree.inOrderTraversal(); // Perform inorder traversal
break;
case 6:
Post(root);
tree.postOrderTraversal(); // Perform postorder traversal
break;
}
} while (ch != 0);
} while (choice != 0); // Exit loop on choice 0

return 0;
}
Loading