This content originally appeared on DEV Community and was authored by Harsh Mishra
Creation of Binary Search Tree (Linked List Implementation)
class BinarySearchTree {
private:
struct Node {
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = nullptr;
right = nullptr;
}
};
Node* root;
public:
// Constructor to initialize the Binary Search Tree
BinarySearchTree() {
root = nullptr;
}
};
First, we will create a class named
BinarySearchTree.-
It will contain a
struct Nodewith the following properties:-
int data: Stores the value of the node. -
Node* left: Points to the left child node. -
Node* right: Points to the right child node. -
Node(int val): Constructor to initializedatawithval, andleftandrightwithnullptr.
-
-
It will contain a property
root:-
Node* root: Points to the root node of the binary search tree.
-
-
We will declare a constructor
BinarySearchTree():- It will initialize the
rootpointer tonullptr, indicating an empty tree.
- It will initialize the
Insertion Operation
private:
// Helper function to insert a value into the tree
Node* insert(Node* node, int value) {
if (node == nullptr) {
return new Node(value);
}
if (value < node->data) {
node->left = insert(node->left, value);
} else if (value > node->data) {
node->right = insert(node->right, value);
}
return node;
}
public:
// Public method to insert a value into the tree
void insert(int value) {
root = insert(root, value);
}
We will define the insertion operation as follows:
-
In the
privatesection:-
Helper Function
insert(Node* node, int value)- This recursive function handles the insertion of a value into the binary search tree.
- If the current node is
nullptr, it creates a newNodewith the given value and returns it. - If the value to be inserted is less than the current node’s data, it recursively inserts the value into the left subtree.
- If the value is greater than the current node’s data, it recursively inserts the value into the right subtree.
- Finally, it returns the updated node.
-
Helper Function
-
In the
publicsection:-
Public Method
insert(int value)- This method is used to insert a value into the binary search tree.
- It calls the helper function
insertwith the root of the tree and the value to be inserted.
-
Public Method
Preorder Traversal
private:
// Helper function for preorder traversal
void preorderTraversal(Node* node) {
if (node == nullptr) {
return;
}
cout << node->data << " ";
preorderTraversal(node->left);
preorderTraversal(node->right);
}
public:
// Public method to start preorder traversal
void preorder() {
preorderTraversal(root);
}
We will define the preorder traversal operation as follows:
-
In the
privatesection:-
Helper Function
preorderTraversal(Node* node)- This recursive function handles the preorder traversal of the binary search tree.
- If the current node is
nullptr, it returns immediately, as there are no nodes to process. - It prints the data of the current node.
- It then recursively performs preorder traversal on the left subtree.
- It recursively performs preorder traversal on the right subtree.
-
Helper Function
-
In the
publicsection:-
Public Method
preorder()- This method is used to start the preorder traversal from the root of the tree.
- It calls the helper function
preorderTraversalwith the root of the tree.
-
Public Method
Level Order Traversal
public:
// Public method to perform level order traversal
void levelOrder() {
if (root == nullptr) {
return;
}
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* node = q.front();
q.pop();
cout << node->data << " ";
if (node->left != nullptr) {
q.push(node->left);
}
if (node->right != nullptr) {
q.push(node->right);
}
}
}
We will define the level order traversal operation as follows:
-
Public Method
levelOrder()- This method performs a level order traversal (also known as breadth-first traversal) of the binary search tree.
- It first checks if the root is
nullptr; if so, it returns immediately. - It uses a queue to keep track of nodes at each level.
- It starts by pushing the root node into the queue.
- While the queue is not empty:
- It dequeues a node and prints its data.
- It enqueues the left child of the node if it is not
nullptr. - It enqueues the right child of the node if it is not
nullptr.
Height of the Tree
public:
// Public method to calculate the height of the tree
int height() {
return height(root);
}
private:
// Helper function to calculate the height of the tree
int height(Node* node) {
if (node == nullptr) {
return 0;
}
int leftHeight = height(node->left);
int rightHeight = height(node->right);
return max(leftHeight, rightHeight) + 1;
}
We will define the height calculation for the binary search tree as follows:
-
Public Method
height()- This method provides a public interface to calculate the height of the entire tree.
- It calls the private helper function
height(Node* node)starting with the root node. - The method returns the result of the helper function, which is the height of the tree.
-
Private Method
height(Node* node)- This recursive helper function calculates the height of the subtree rooted at
node. -
Base Case: If the
nodeisnullptr(i.e., if the tree or subtree is empty), the height is0. This is because an empty tree has no nodes, and hence its height is considered0. - Recursive Case:
- The function calculates the height of the left subtree by calling itself with
node->left. - It calculates the height of the right subtree by calling itself with
node->right. - It then returns the maximum of the two heights (
leftHeightandrightHeight) plus1. The+1accounts for the current node. - The result is the height of the subtree rooted at the current node.
- This recursive helper function calculates the height of the subtree rooted at
Depth of a Node
public:
// Public method to calculate the depth of a specific node
int depth(int value) {
return depth(root, value);
}
private:
// Helper function to calculate the depth of a node with a specific value
int depth(Node* node, int value) {
if (node == nullptr) {
return -1; // Node not found, return -1
}
if (node->data == value) {
return 0; // Node found, depth is 0 (current node)
}
// Recursively search for the node in the left or right subtree
int leftDepth = depth(node->left, value);
int rightDepth = depth(node->right, value);
if (leftDepth == -1 && rightDepth == -1) {
return -1; // Node not found in either subtree
}
// Return the depth if the node is found in one of the subtrees
return max(leftDepth, rightDepth) + 1;
}
Explanation:
-
In the
publicsection:-
Public Method
depth(int value)- This method provides a public interface to calculate the depth of a specific node identified by
value. - It calls the private helper function
depth(Node* node, int value)starting with the root node. - The method returns the result of the helper function, which is the depth of the node with the given value.
- This method provides a public interface to calculate the depth of a specific node identified by
-
Public Method
-
In the
privatesection:-
Helper Function
depth(Node* node, int value)-
Base Case (Node is
nullptr): - If the
nodeisnullptr(i.e., the subtree is empty or the node does not exist), the function returns-1to indicate that the node was not found. - Node Found:
- If
node->datamatches thevalue, the function returns0because the node itself is at depth0. - Recursive Case:
- The function recursively searches for the node in the left subtree by calling
depth(node->left, value). - It also recursively searches for the node in the right subtree by calling
depth(node->right, value). - Check Node Existence:
- If the node is not found in either subtree (
leftDepth == -1 && rightDepth == -1), the function returns-1indicating that the node does not exist. - Return Depth:
- If the node is found in one of the subtrees, the function returns the maximum depth from the left or right subtree plus
1. The+1accounts for the current node level. - This calculation ensures that the depth returned represents the distance from the root to the node with the specified value.
-
Base Case (Node is
-
Helper Function
Searching Operation
public:
// Public method to search for a value in the tree
bool search(int value) {
return search(root, value);
}
private:
// Helper function to search for a value in the subtree rooted at node
bool search(Node* node, int value) {
if (node == nullptr) {
return false; // Value not found
}
if (node->data == value) {
return true; // Value found
}
if (value < node->data) {
return search(node->left, value); // Search in the left subtree
} else {
return search(node->right, value); // Search in the right subtree
}
}
We will define the search functionality for the binary search tree as follows:
-
Public Method
search(int value)- This method provides a public interface to search for a specific
valuein the tree. - It calls the private helper function
search(Node* node, int value)starting with the root node. - The method returns the result of the helper function, which is a boolean indicating whether the value is present in the tree.
- This method provides a public interface to search for a specific
-
Private Method
search(Node* node, int value)- This recursive helper function searches for a
valuein the subtree rooted atnode. - Base Case:
- If
nodeisnullptr(i.e., if the subtree is empty), the function returnsfalse, indicating that the value is not found in this path. - Value Found Case:
- If
node->datais equal to thevalue, the function returnstrue, indicating that the value has been found. - Recursive Case:
- If the
valueis less thannode->data, the function recursively searches in the left subtree by calling itself withnode->left. - If the
valueis greater thannode->data, the function recursively searches in the right subtree by calling itself withnode->right. - The function returns
trueif the value is found in either subtree, orfalseif it is not found in either.
- This recursive helper function searches for a
Deletion Operation
public:
// Public method to delete a value from the tree
void deleteValue(int value) {
root = deleteNode(root, value);
}
private:
// Helper function to delete a value from the subtree rooted at node
Node* deleteNode(Node* node, int value) {
if (node == nullptr) {
return nullptr; // Value not found
}
// Traverse the tree to find the node to delete
if (value < node->data) {
node->left = deleteNode(node->left, value); // Go left
} else if (value > node->data) {
node->right = deleteNode(node->right, value); // Go right
} else {
// Node with the value to be deleted found
// Case 1: Node with only one child or no child
if (node->left == nullptr) {
Node* temp = node->right;
delete node; // Free memory
return temp;
} else if (node->right == nullptr) {
Node* temp = node->left;
delete node; // Free memory
return temp;
}
// Case 2: Node with two children
Node* temp = minValueNode(node->right); // Get the in-order successor
node->data = temp->data; // Copy the in-order successor's value to this node
node->right = deleteNode(node->right, temp->data); // Delete the in-order successor
}
return node;
}
// Helper function to find the node with the minimum value in the subtree
Node* minValueNode(Node* node) {
Node* current = node;
while (current && current->left != nullptr) {
current = current->left; // Traverse to the leftmost leaf
}
return current;
}
We will define the deletion functionality for the binary search tree as follows:
-
Public Method
deleteValue(int value)- This method provides a public interface to delete a specific
valuefrom the tree. - It calls the private helper function
deleteNode(Node* node, int value)starting with the root node. - The method updates the
rootwith the result of the helper function after the deletion process.
- This method provides a public interface to delete a specific
-
Private Method
deleteNode(Node* node, int value)- This recursive helper function deletes a
valuefrom the subtree rooted atnode. - Base Case:
- If
nodeisnullptr, it returnsnullptr, indicating that the value was not found in this path. - Traversal Case:
- If
valueis less thannode->data, the function recursively deletes the value from the left subtree. - If
valueis greater thannode->data, the function recursively deletes the value from the right subtree. - Node Found Case:
-
Case 1: Node with Only One Child or No Child
- If the node to be deleted has no left child, it returns the right child, effectively bypassing the node.
- If the node to be deleted has no right child, it returns the left child, effectively bypassing the node.
-
Case 2: Node with Two Children
- It finds the in-order successor (the smallest node in the right subtree) using the
minValueNodefunction. - It replaces the value of the node to be deleted with the in-order successor’s value.
- It then recursively deletes the in-order successor from the right subtree.
- It finds the in-order successor (the smallest node in the right subtree) using the
- The function returns the potentially modified subtree after deletion.
- This recursive helper function deletes a
-
Private Method
minValueNode(Node* node)- This helper function finds and returns the node with the minimum value in the subtree rooted at
node. - It traverses the leftmost path to find the smallest node.
- This helper function finds and returns the node with the minimum value in the subtree rooted at
Full Code Implementation
class BinarySearchTree {
private:
struct Node {
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = nullptr;
right = nullptr;
}
};
Node* root;
public:
BinarySearchTree() {
root = nullptr;
}
void insert(int value) {
root = insert(root, value);
}
void preorder() {
preorderTraversal(root);
}
void levelOrder() {
if (root == nullptr) {
return;
}
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* node = q.front();
q.pop();
cout << node->data << " ";
if (node->left != nullptr) {
q.push(node->left);
}
if (node->right != nullptr) {
q.push(node->right);
}
}
}
int height() {
return height(root);
}
int depth(int value) {
return depth(root, value);
}
bool search(int value) {
return search(root, value);
}
void deleteValue(int value) {
root = deleteNode(root, value);
}
private:
Node* insert(Node* node, int value) {
if (node == nullptr) {
return new Node(value);
}
if (value < node->data) {
node->left = insert(node->left, value);
} else if (value > node->data) {
node->right = insert(node->right, value);
}
return node;
}
void preorderTraversal(Node* node) {
if (node == nullptr) {
return;
}
cout << node->data << " ";
preorderTraversal(node->left);
preorderTraversal(node->right);
}
int height(Node* node) {
if (node == nullptr) {
return 0;
}
int leftHeight = height(node->left);
int rightHeight = height(node->right);
return max(leftHeight, rightHeight) + 1;
}
int depth(Node* node, int value) {
if (node == nullptr) {
return -1;
}
if (node->data == value) {
return 0;
}
int leftDepth = depth(node->left, value);
int rightDepth = depth(node->right, value);
if (leftDepth == -1 && rightDepth == -1) {
return -1;
}
return max(leftDepth, rightDepth) + 1;
}
bool search(Node* node, int value) {
if (node == nullptr) {
return false;
}
if (node->data == value) {
return true;
}
if (value < node->data) {
return search(node->left, value);
} else {
return search(node->right, value);
}
}
Node* deleteNode(Node* node, int value) {
if (node == nullptr) {
return nullptr;
}
if (value < node->data) {
node->left = deleteNode(node->left, value);
} else if (value > node->data) {
node->right = deleteNode(node->right, value);
} else {
if (node->left == nullptr) {
Node* temp = node->right;
delete node;
return temp;
} else if (node->right == nullptr) {
Node* temp = node->left;
delete node;
return temp;
}
Node* temp = minValueNode(node->right);
node->data = temp->data;
node->right = deleteNode(node->right, temp->data);
}
return node;
}
Node* minValueNode(Node* node) {
Node* current = node;
while (current && current->left != nullptr) {
current = current->left;
}
return current;
}
};
This content originally appeared on DEV Community and was authored by Harsh Mishra
Harsh Mishra | Sciencx (2024-08-04T14:38:47+00:00) Binary Search Tree, Code ↔ Language. Retrieved from https://www.scien.cx/2024/08/04/binary-search-tree-code-%e2%86%94-language/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.