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
insertIntoBST
puts 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 givendata
andNULL
children.
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
root
isNULL
, it means we’ve found the correct empty spot. Create a newNode
with the givendata
and return it. This new node becomes theroot
of a new subtree (or a leaf node). - Recursive Step:
- If
data
is greater thanroot->data
, the new node belongs in the right subtree. Recursively callinsertIntoBST
onroot->right
and assign the returned (potentially new) subtree toroot->right
. - If
data
is less than or equal toroot->data
(handling duplicates by placing them on the left), the new node belongs in the left subtree. Recursively callinsertIntoBST
onroot->left
and 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
-1
is entered (acting as a sentinel value to stop input). - For each valid integer, it calls
insertIntoBST
to insert it into theroot
.
Node* &root
: The&
symbol meansroot
is passed by reference. This is crucial becauseinsertIntoBST
returns the new root (if the initialroot
wasNULL
), and we need to update theroot
pointer inmain
directly.
5. levelOrderTraversal(Node* root)
- Purpose: Prints the nodes of the BST level by level (Breadth-First Search - BFS).
- Logic:
- Uses a
queue<Node*> Q
to store nodes to be visited. - A
NULL
marker is used in the queue to indicate the end of a level. - Initialization: Push the
root
and then aNULL
marker 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
NULL
marker to delineate the next level.
- This signifies the end of a level. Print a new line (
- If
FrontNode
is a valid node:- Print its
data
. - If
FrontNode->left
exists, enqueue it. - If
FrontNode->right
exists, enqueue it.
- Print its
- Dequeue
- Uses a
6. Complexity Analysis
-
For
insertIntoBST
andtakeinput
:- Time Complexity:
O(H)
for each insertion, whereH
is the height of the BST.- Best Case (Balanced BST):
H = log N
. So,O(log N)
per insertion. ForN
insertions:O(N log N)
. - Worst Case (Skewed BST/Linear Chain):
H = N
. So,O(N)
per insertion. ForN
insertions: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)
W
is the maximum width of the tree (max number of nodes at any level). In the worst case (e.g., a complete binary tree),W
can beO(N)
. So,O(N)
space for the queue.
- Time Complexity: