#22.Journey to DSA in C++

#22.Journey to DSA in C++

ยท

5 min read

Unlocking the Magic of Binary Search Trees ๐ŸŒณ - Your Guide to BST Operations in C++

Hello, dear readers! Today, I'm thrilled to take you on a journey into the fascinating world of Binary Search Trees (BST) and explore various operations that can be performed on them. From searching to insertion, deletion to finding the floor and ceiling values, and even discovering the kth smallest element, we're about to dive into it all. ๐Ÿš€

๐ŸŒฟ Why Binary Search Trees? Let's start our adventure by understanding why Binary Search Trees are so important. Binary Search Trees are data structures that provide efficient data retrieval, insertion, and deletion operations. They are organized in a hierarchical manner, making them a perfect choice for storing and managing data. The magic lies in their ability to maintain data in a sorted order, which simplifies various operations.

Now, let's explore some fundamental operations on BST.

๐Ÿ” Searching in a BST (Recursive) When I want to find a specific element in a BST, I use a recursive approach. This method makes use of the tree's structure, enabling us to narrow down the search quickly. Here's a simple C++ program for searching in a BST recursively:

๐Ÿ” Searching in a BST (Recursive)

#include <iostream>

struct Node {
    int data;
    Node* left;
    Node* right;
};

bool searchRecursive(Node* root, int key) {
    if (root == nullptr) return false;
    if (root->data == key) return true;
    if (key < root->data)
        return searchRecursive(root->left, key);
    else
        return searchRecursive(root->right, key);
}

int main() {
    // Create a sample BST
    Node* root = new Node{10, nullptr, nullptr};
    root->left = new Node{5, nullptr, nullptr};
    root->right = new Node{15, nullptr, nullptr};
    root->left->left = new Node{3, nullptr, nullptr};
    root->left->right = new Node{7, nullptr, nullptr};

    int key = 7;
    if (searchRecursive(root, key)) {
        std::cout << key << " found in the BST." << std::endl;
    } else {
        std::cout << key << " not found in the BST." << std::endl;
    }

    return 0;
}

๐Ÿ” Searching in a BST (Iterative) An iterative approach to searching in a BST can also be quite handy. Here's how we do it:

๐Ÿ” Searching in a BST (Iterative)

#include <iostream>

struct Node {
    int data;
    Node* left;
    Node* right;
};

bool searchIterative(Node* root, int key) {
    while (root) {
        if (root->data == key) return true;
        if (key < root->data)
            root = root->left;
        else
            root = root->right;
    }
    return false;
}

int main() {
    // Create a sample BST
    Node* root = new Node{10, nullptr, nullptr};
    root->left = new Node{5, nullptr, nullptr};
    root->right = new Node{15, nullptr, nullptr};
    root->left->left = new Node{3, nullptr, nullptr};
    root->left->right = new Node{7, nullptr, nullptr};

    int key = 7;
    if (searchIterative(root, key)) {
        std::cout << key << " found in the BST." << std::endl;
    } else {
        std::cout << key << " not found in the BST." << std::endl;
    }

    return 0;
}

๐ŸŒฑ Insertion in BST When I need to add a new element to a BST, I follow these steps. Inserting a node into a BST involves finding the appropriate position for the new node and linking it properly:

codeNode* insert(Node* root, int key) {
    if (root == nullptr) {
        return createNode(key);
    }
    if (key < root->data) {
        root->left = insert(root->left, key);
    } else {
        root->right = insert(root->right, key);
    }
    return root;
}

๐Ÿ—‘๏ธ Deletion in a BST Deleting a node in a BST can be a bit tricky, but it's a fundamental operation. Here's a simple program for deletion:

 codeNode* deleteNode(Node* root, int key) {
    if (root == nullptr) return root;
    // Implement the deletion logic here
}

๐Ÿ“ Floor and Ceiling in a BST The floor of a given value in a BST is the largest value in the tree that is less than or equal to the given value. The ceiling is the smallest value that is greater than or equal to the given value. Here's how you can find them in a BST:

#include <iostream>

struct Node {
    int data;
    Node* left;
    Node* right;
};

void floorCeiling(Node* root, int key, int& floor, int& ceiling) {
    while (root) {
        if (root->data == key) {
            floor = root->data;
            ceiling = root->data;
            return;
        } else if (key < root->data) {
            ceiling = root->data;
            root = root->left;
        } else {
            floor = root->data;
            root = root->right;
        }
    }
}

int main() {
    // Create a sample BST
    Node* root = new Node{10, nullptr, nullptr};
    root->left = new Node{5, nullptr, nullptr};
    root->right = new Node{15, nullptr, nullptr};
    root->left->left = new Node{3, nullptr, nullptr};
    root->left->right = new Node{7, nullptr, nullptr};

    int key = 6;
    int floor = -1, ceiling = -1;
    floorCeiling(root, key, floor, ceiling);

    if (floor != -1) {
        std::cout << "Floor(" << key << ") = " << floor << std::endl;
    } else {
        std::cout << "No floor value found for " << key << std::endl;
    }

    if (ceiling != -1) {
        std::cout << "Ceiling(" << key << ") = " << ceiling << std::endl;
    } else {
        std::cout << "No ceiling value found for " << key << std::endl;
    }

    return 0;
}

๐Ÿ” Kth Smallest Element in a BST Finding the kth smallest element in a BST can be accomplished using in-order traversal. Here's how to do it:

#include <iostream>

struct Node {
    int data;
    Node* left;
    Node* right;
};

int kthSmallest(Node* root, int& k) {
    if (root == nullptr) return -1;
    int leftValue = kthSmallest(root->left, k);
    if (leftValue != -1) return leftValue;
    k--;
    if (k == 0) return root->data;
    return kthSmallest(root->right, k);
}

int main() {
    // Create a sample BST
    Node* root = new Node{10, nullptr, nullptr};
    root->left = new Node{5, nullptr, nullptr};
    root->right = new Node{15, nullptr, nullptr};
    root->left->left = new Node{3, nullptr, nullptr};
    root->left->right = new Node{7, nullptr, nullptr};

    int k = 3; // Find the 3rd smallest element
    int result = kthSmallest(root, k);

    if (result != -1) {
        std::cout << "The " << k << "th smallest element is: " << result << std::endl;
    } else {
        std::cout << "No " << k << "th smallest element found." << std::endl;
    }

    return 0;
}

These programs demonstrate how to find the floor and ceiling values as well as the kth smallest element in a Binary Search Tree. Feel free to adapt and expand upon them for your specific use cases! ๐ŸŒณ๐Ÿ“๐Ÿ”

๐ŸŒŸ Conclusion In our journey today, we've scratched the surface of Binary Search Trees and their fundamental operations. I hope you found this introduction enlightening! Stay tuned for our upcoming sessions, where we'll dive deeper into each of these operations with clear examples and detailed programs in C++. ๐ŸŽ‰

Thank you for joining me on this journey, and I can't wait to explore the magic of DSA in C++ together! ๐ŸŒณ๐Ÿ”๐ŸŒŸ

ย