BST Implementation
#include <bits/stdc++.h> // Includes common standard libraries (iostream, queue, etc.)
using namespace std; // Use the standard namespace
// Definition of a Node in the Binary Search Treeclass Node {public: int data; // Data value of the node Node* left; // Pointer to the left child Node* right; // Pointer to the right child
// Constructor to initialize a new node Node(int data) { this->data = data; this->left = NULL; // Initially, left child is NULL this->right = NULL; // Initially, right child is NULL }};
// Function to insert a new node with 'data' into the BST// Returns the root of the (potentially updated) subtreeNode* insertIntoBST(Node* root, int data) { // Base Case: If the current subtree is empty (found insertion point) if(root == NULL) { root = new Node(data); // Create a new node return root; // This new node becomes the root of this subtree }
// Recursive Step: Decide whether to go right or left if(data > root->data) { // If data is greater, insert into the right subtree root->right = insertIntoBST(root->right, data); } else { // data <= root->data (handles duplicates by placing them on the left) // If data is smaller or equal, insert into the left subtree root->left = insertIntoBST(root->left, data); }
return root; // Return the current root (after potentially updating its children)}
// Function to take input from the user and build the BST// 'root' is passed by reference (Node* &root) so the actual root pointer in main can be updatedvoid takeinput(Node* &root) { int data; cout << "Enter data for node (enter -1 to stop): "; cin >> data; // Read the first data element
// Loop until the sentinel value -1 is entered while(data != -1) { root = insertIntoBST(root, data); // Insert data into the BST cout << "Enter data for node (enter -1 to stop): "; cin >> data; // Read the next data element }}
// Function to perform Level Order Traversal (BFS) of the BST// Prints nodes level by level, with newlines between levelsvoid levelOrderTraversal(Node* root) { // If the tree is empty, nothing to traverse if(root == NULL) { return; }
queue<Node*> Q; // Create a queue for BFS Q.push(root); // Push the root node Q.push(NULL); // Push a NULL marker to signify the end of the first level
// Loop until the queue is empty while(!Q.empty()) { Node* FrontNode = Q.front(); // Get the front node Q.pop(); // Remove it from the queue
if(FrontNode == NULL) { // If FrontNode is NULL, it means we have finished a level cout << endl; // Print a newline to move to the next level
// If there are still nodes in the queue, it means there's a next level. // Push another NULL marker to delineate the end of that next level. if(!Q.empty()) { Q.push(NULL); } } else { // If FrontNode is a valid node, print its data cout << FrontNode->data << " ";
// Enqueue its left child if it exists if(FrontNode->left) { Q.push(FrontNode->left); }
// Enqueue its right child if it exists if(FrontNode->right) { Q.push(FrontNode->right); } } }}
int main() { Node* root = NULL; // Initialize the root of the BST to NULL
// Build the BST by taking input from the user cout << "--- Creating Binary Search Tree ---" << endl; takeinput(root);
// Perform and print the Level Order Traversal of the created BST cout << endl << "Level Order Traversal of BST:" << endl; levelOrderTraversal(root); cout << endl; // Extra newline for formatting
return 0; // End of the program}
/*Example INPUT:Enter data for node (enter -1 to stop): 50Enter data for node (enter -1 to stop): 20Enter data for node (enter -1 to stop): 70Enter data for node (enter -1 to stop): 10Enter data for node (enter -1 to stop): 30Enter data for node (enter -1 to stop): 60Enter data for node (enter -1 to stop): 80Enter data for node (enter -1 to stop): -1
Expected Level Order Traversal Output:5020 7010 30 60 80*/Here are quick revision notes and the commented code for a Binary Search Tree (BST) implementation, including insertion and level-order traversal, formatted in Markdown for easy copying.
Binary Search Tree (BST) Quick Revision Notes
1. Binary Search Tree (BST) Properties
- A Binary Search Tree (BST) is a special type of binary tree where for every node:
- All nodes in its left subtree have values less than the node’s data.
- All nodes in its right subtree have values greater than the node’s data.
- Both the left and right subtrees must also be Binary Search Trees.
- No Duplicates (typically): Most BST implementations assume no duplicate values. If duplicates are allowed, a consistent policy must be followed (e.g., always insert duplicates into the left subtree or always into the right subtree). This code’s
insertIntoBSTputs duplicates in the left. - Ordering: The BST property ensures that an in-order traversal of the tree will yield the elements in sorted (ascending) order.
2. Node Class
- Represents a single node in the BST.
data: Stores the integer value of the node.left: Pointer to the left child node.right: Pointer to the right child node.Node(int data): Constructor to initialize a new node with givendataandNULLchildren.
3. insertIntoBST(Node* root, int data) (Recursive Insertion)
- Purpose: Inserts a new data value into the correct position in the BST.
- Logic:
- Base Case: If
rootisNULL, it means we’ve found the correct empty spot. Create a newNodewith the givendataand return it. This new node becomes therootof a new subtree (or a leaf node). - Recursive Step:
- If
datais greater thanroot->data, the new node belongs in the right subtree. Recursively callinsertIntoBSTonroot->rightand assign the returned (potentially new) subtree toroot->right. - If
datais less than or equal toroot->data(handling duplicates by placing them on the left), the new node belongs in the left subtree. Recursively callinsertIntoBSTonroot->leftand assign the returned (potentially new) subtree toroot->left.
- If
- Return: After the recursive call, return the current
root(which might have been updated with a new child).
- Base Case: If
4. takeinput(Node* &root)
- Purpose: Reads integer data from standard input to build the BST.
- Logic:
- Prompts the user to enter data.
- Reads integers one by one until
-1is entered (acting as a sentinel value to stop input). - For each valid integer, it calls
insertIntoBSTto insert it into theroot.
Node* &root: The&symbol meansrootis passed by reference. This is crucial becauseinsertIntoBSTreturns the new root (if the initialrootwasNULL), and we need to update therootpointer inmaindirectly.
5. levelOrderTraversal(Node* root)
- Purpose: Prints the nodes of the BST level by level (Breadth-First Search - BFS).
- Logic:
- Uses a
queue<Node*> Qto store nodes to be visited. - A
NULLmarker is used in the queue to indicate the end of a level. - Initialization: Push the
rootand then aNULLmarker to the queue. - Loop: While the queue is not empty:
- Dequeue
FrontNode. - If
FrontNode == NULL:- This signifies the end of a level. Print a new line (
endl). - If the queue is not empty after this (meaning there are still nodes in the next level), push another
NULLmarker to delineate the next level.
- This signifies the end of a level. Print a new line (
- If
FrontNodeis a valid node:- Print its
data. - If
FrontNode->leftexists, enqueue it. - If
FrontNode->rightexists, enqueue it.
- Print its
- Dequeue
- Uses a
6. Complexity Analysis
-
For
insertIntoBSTandtakeinput:- Time Complexity:
O(H)for each insertion, whereHis the height of the BST.- Best Case (Balanced BST):
H = log N. So,O(log N)per insertion. ForNinsertions:O(N log N). - Worst Case (Skewed BST/Linear Chain):
H = N. So,O(N)per insertion. ForNinsertions:O(N^2).
- Best Case (Balanced BST):
- Space Complexity:
O(H)due to recursion stack for insertion.
- Time Complexity:
-
For
levelOrderTraversal:- Time Complexity:
O(N)- Every node is enqueued and dequeued exactly once.
- Space Complexity:
O(W)Wis the maximum width of the tree (max number of nodes at any level). In the worst case (e.g., a complete binary tree),Wcan beO(N). So,O(N)space for the queue.
- Time Complexity: