#include <stdio.h>
#include <stdlib.h>

// Structure for a node in the BST
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};

// Function to create a new node
struct Node* createNode(int data) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->left = newNode->right = NULL;
    return newNode;
}

// Function to insert a new node in the BST
struct Node* insert(struct Node* root, int data) {
    if (root == NULL) {
        return createNode(data);
    }

    if (data < root->data) {
        root->left = insert(root->left, data);
    } else if (data > root->data) {
        root->right = insert(root->right, data);
    }

    return root;
}

// Function to find the minimum value node in the right subtree
struct Node* findMin(struct Node* root) {
    while (root->left != NULL) {
        root = root->left;
    }
    return root;
}

// Function to delete a node in the BST
struct Node* deleteNode(struct Node* root, int data) {
    if (root == NULL) {
        return root;
    }

    // Find the node to be deleted
    if (data < root->data) {
        root->left = deleteNode(root->left, data);
    } else if (data > root->data) {
        root->right = deleteNode(root->right, data);
    } else {
        // Node found: let's handle the three cases

        // Case 1: No child
        if (root->left == NULL && root->right == NULL) {
            free(root);
            return NULL;
        }
        
        // Case 2: One child (right)
        else if (root->left == NULL) {
            struct Node* temp = root->right;
            free(root);
            return temp;
        }

        // Case 2: One child (left)
        else if (root->right == NULL) {
            struct Node* temp = root->left;
            free(root);
            return temp;
        }

        // Case 3: Two children
        struct Node* temp = findMin(root->right);
        root->data = temp->data;
        root->right = deleteNode(root->right, temp->data);
    }
    return root;
}

// Function to perform inorder traversal of the BST
void inorder(struct Node* root) {
    if (root != NULL) {
        inorder(root->left);
        printf("%d ", root->data);
        inorder(root->right);
    }
}

int main() {
    struct Node* root = NULL;

    // Insert nodes into the BST
    root = insert(root, 50);
    root = insert(root, 30);
    root = insert(root, 20);
    root = insert(root, 40);
    root = insert(root, 70);
    root = insert(root, 60);
    root = insert(root, 80);

    printf("Inorder traversal before deletion: ");
    inorder(root);
    printf("\n");

    // Deleting nodes
    root = deleteNode(root, 20); // Deleting a leaf node
    printf("Inorder traversal after deleting 20: ");
    inorder(root);
    printf("\n");

    root = deleteNode(root, 30); // Deleting a node with one child
    printf("Inorder traversal after deleting 30: ");
    inorder(root);
    printf("\n");

    root = deleteNode(root, 50); // Deleting a node with two children
    printf("Inorder traversal after deleting 50: ");
    inorder(root);
    printf("\n");

    return 0;
}

Explanation:

  1. Node Structure:
    • We define a Node structure that holds an integer data, a pointer to the left child, and a pointer to the right child.
  2. createNode:
    • Creates a new node with the given value, setting its left and right pointers to NULL.
  3. insert:
    • Inserts a new node into the BST. If the tree is empty, it creates the root node.
    • Otherwise, it compares the data with the current node and inserts it into the left or right subtree accordingly.
  4. findMin:
    • Finds the node with the minimum value in a subtree, which is used to find the inorder successor during deletion.
  5. deleteNode:
    • Recursively locates the node to be deleted.
    • Handles the three cases of deletion:
      • For a leaf node, it frees the node.
      • For a node with one child, it replaces the node with its child.
      • For a node with two children, it finds the inorder successor, replaces the node’s value with that of the successor, and deletes the successor.
  6. inorder:
    • Prints the inorder traversal of the tree, which outputs the BST nodes in a sorted order.
  7. main:
    • Demonstrates the insertion of nodes, deletion of specific nodes, and prints the inorder traversal before and after each deletion.

Output:

Inorder traversal before deletion: 20 30 40 50 60 70 80 
Inorder traversal after deleting 20: 30 40 50 60 70 80 
Inorder traversal after deleting 30: 40 50 60 70 80 
Inorder traversal after deleting 50: 40 60 70 80 

Explanation of the Output:

  • Initially, the BST has nodes 20, 30, 40, 50, 60, 70, and 80.
  • After deleting 20 (a leaf), it’s removed directly.
  • Deleting 30 (which has one child, 40), results in 40 taking its place.
  • Deleting 50 (which has two children) involves replacing 50 with its inorder successor 60, then removing 60.

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights