CCCPaste
/*
Write a program in ā€˜C’ language for the creation of a Red Black tree. Also, implement insertion and deletion operations.
*/

#include 
#include 

// Enum for node colors
typedef enum { RED, BLACK } Color;

// Red-Black Tree node structure
typedef struct Node {
    int data;
    Color color;
    struct Node *left, *right, *parent;
} Node;

// Global root node
Node *root = NULL;

// Function to create a new node
Node* createNode(int data) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->color = RED; // New nodes are always red initially
    newNode->left = newNode->right = newNode->parent = NULL;
    return newNode;
}

// Function to perform left rotation
void leftRotate(Node *x) {
    Node *y = x->right;
    x->right = y->left;
    
    if (y->left != NULL)
        y->left->parent = x;
    
    y->parent = x->parent;
    
    if (x->parent == NULL)
        root = y;
    else if (x == x->parent->left)
        x->parent->left = y;
    else
        x->parent->right = y;
    
    y->left = x;
    x->parent = y;
}

// Function to perform right rotation
void rightRotate(Node *y) {
    Node *x = y->left;
    y->left = x->right;
    
    if (x->right != NULL)
        x->right->parent = y;
    
    x->parent = y->parent;
    
    if (y->parent == NULL)
        root = x;
    else if (y == y->parent->left)
        y->parent->left = x;
    else
        y->parent->right = x;
    
    x->right = y;
    y->parent = x;
}

// Function to fix violations after insertion
void fixInsert(Node *k) {
    Node *uncle;
    
    while (k->parent != NULL && k->parent->color == RED) {
        if (k->parent == k->parent->parent->left) {
            uncle = k->parent->parent->right;
            
            // Case 1: Uncle is red
            if (uncle != NULL && uncle->color == RED) {
                k->parent->color = BLACK;
                uncle->color = BLACK;
                k->parent->parent->color = RED;
                k = k->parent->parent;
            } else {
                // Case 2: k is right child
                if (k == k->parent->right) {
                    k = k->parent;
                    leftRotate(k);
                }
                // Case 3: k is left child
                k->parent->color = BLACK;
                k->parent->parent->color = RED;
                rightRotate(k->parent->parent);
            }
        } else {
            uncle = k->parent->parent->left;
            
            // Case 1: Uncle is red
            if (uncle != NULL && uncle->color == RED) {
                k->parent->color = BLACK;
                uncle->color = BLACK;
                k->parent->parent->color = RED;
                k = k->parent->parent;
            } else {
                // Case 2: k is left child
                if (k == k->parent->left) {
                    k = k->parent;
                    rightRotate(k);
                }
                // Case 3: k is right child
                k->parent->color = BLACK;
                k->parent->parent->color = RED;
                leftRotate(k->parent->parent);
            }
        }
        
        if (k == root) break;
    }
    
    root->color = BLACK;
}

// Insertion function
void insert(int data) {
    Node *newNode = createNode(data);
    Node *y = NULL;
    Node *x = root;
    
    // Standard BST insertion
    while (x != NULL) {
        y = x;
        if (newNode->data < x->data)
            x = x->left;
        else
            x = x->right;
    }
    
    newNode->parent = y;
    
    if (y == NULL)
        root = newNode;
    else if (newNode->data < y->data)
        y->left = newNode;
    else
        y->right = newNode;
    
    // Fix Red-Black Tree violations
    fixInsert(newNode);
}

// Function to find the minimum value node
Node* minValueNode(Node *node) {
    Node *current = node;
    while (current->left != NULL)
        current = current->left;
    return current;
}

// Function to fix violations after deletion
void fixDelete(Node *x) {
    Node *sibling;
    
    while (x != root && (x == NULL || x->color == BLACK)) {
        if (x == x->parent->left) {
            sibling = x->parent->right;
            
            // Case 1: Sibling is red
            if (sibling->color == RED) {
                sibling->color = BLACK;
                x->parent->color = RED;
                leftRotate(x->parent);
                sibling = x->parent->right;
            }
            
            // Case 2: Both sibling's children are black
            if ((sibling->left == NULL || sibling->left->color == BLACK) &&
                (sibling->right == NULL || sibling->right->color == BLACK)) {
                sibling->color = RED;
                x = x->parent;
            } else {
                // Case 3: Sibling's right child is black
                if (sibling->right == NULL || sibling->right->color == BLACK) {
                    if (sibling->left != NULL)
                        sibling->left->color = BLACK;
                    sibling->color = RED;
                    rightRotate(sibling);
                    sibling = x->parent->right;
                }
                
                // Case 4: Sibling's right child is red
                sibling->color = x->parent->color;
                x->parent->color = BLACK;
                if (sibling->right != NULL)
                    sibling->right->color = BLACK;
                leftRotate(x->parent);
                x = root;
            }
        } else {
            sibling = x->parent->left;
            
            // Case 1: Sibling is red
            if (sibling->color == RED) {
                sibling->color = BLACK;
                x->parent->color = RED;
                rightRotate(x->parent);
                sibling = x->parent->left;
            }
            
            // Case 2: Both sibling's children are black
            if ((sibling->left == NULL || sibling->left->color == BLACK) &&
                (sibling->right == NULL || sibling->right->color == BLACK)) {
                sibling->color = RED;
                x = x->parent;
            } else {
                // Case 3: Sibling's left child is black
                if (sibling->left == NULL || sibling->left->color == BLACK) {
                    if (sibling->right != NULL)
                        sibling->right->color = BLACK;
                    sibling->color = RED;
                    leftRotate(sibling);
                    sibling = x->parent->left;
                }
                
                // Case 4: Sibling's left child is red
                sibling->color = x->parent->color;
                x->parent->color = BLACK;
                if (sibling->left != NULL)
                    sibling->left->color = BLACK;
                rightRotate(x->parent);
                x = root;
            }
        }
    }
    
    if (x != NULL)
        x->color = BLACK;
}

// Transplant function for deletion
void transplant(Node *u, Node *v) {
    if (u->parent == NULL)
        root = v;
    else if (u == u->parent->left)
        u->parent->left = v;
    else
        u->parent->right = v;
    
    if (v != NULL)
        v->parent = u->parent;
}

// Deletion function
void deleteNode(int data) {
    Node *z = root;
    Node *x, *y;
    
    // Find the node to delete
    while (z != NULL) {
        if (data == z->data)
            break;
        else if (data < z->data)
            z = z->left;
        else
            z = z->right;
    }
    
    if (z == NULL) {
        printf("Node with data %d not found!\n", data);
        return;
    }
    
    y = z;
    Color yOriginalColor = y->color;
    
    if (z->left == NULL) {
        x = z->right;
        transplant(z, z->right);
    } else if (z->right == NULL) {
        x = z->left;
        transplant(z, z->left);
    } else {
        y = minValueNode(z->right);
        yOriginalColor = y->color;
        x = y->right;
        
        if (y->parent == z) {
            if (x != NULL)
                x->parent = y;
        } else {
            transplant(y, y->right);
            y->right = z->right;
            y->right->parent = y;
        }
        
        transplant(z, y);
        y->left = z->left;
        y->left->parent = y;
        y->color = z->color;
    }
    
    free(z);
    
    if (yOriginalColor == BLACK && x != NULL)
        fixDelete(x);
}

// Inorder traversal
void inorder(Node *node) {
    if (node == NULL) return;
    inorder(node->left);
    printf("%d(%s) ", node->data, node->color == RED ? "RED" : "BLACK");
    inorder(node->right);
}

// Preorder traversal
void preorder(Node *node) {
    if (node == NULL) return;
    printf("%d(%s) ", node->data, node->color == RED ? "RED" : "BLACK");
    preorder(node->left);
    preorder(node->right);
}

// Function to display the tree
void displayTree() {
    printf("Inorder traversal: ");
    inorder(root);
    printf("\n");
    
    printf("Preorder traversal: ");
    preorder(root);
    printf("\n\n");
}

// Function to search for a node
Node* search(int data) {
    Node *current = root;
    while (current != NULL) {
        if (data == current->data)
            return current;
        else if (data < current->data)
            current = current->left;
        else
            current = current->right;
    }
    return NULL;
}

int main() {
    int choice, data;
    Node *result;
    
    printf("Red-Black Tree Implementation\n");
    printf("=============================\n");
    
    while (1) {
        printf("\nMenu:\n");
        printf("1. Insert\n");
        printf("2. Delete\n");
        printf("3. Search\n");
        printf("4. Display Tree\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("Enter data to insert: ");
                scanf("%d", &data);
                insert(data);
                printf("Node %d inserted successfully.\n", data);
                displayTree();
                break;
                
            case 2:
                printf("Enter data to delete: ");
                scanf("%d", &data);
                deleteNode(data);
                printf("Node %d deleted successfully.\n", data);
                displayTree();
                break;
                
            case 3:
                printf("Enter data to search: ");
                scanf("%d", &data);
                result = search(data);
                if (result != NULL)
                    printf("Node %d found in the tree.\n", data);
                else
                    printf("Node %d not found in the tree.\n", data);
                break;
                
            case 4:
                displayTree();
                break;
                
            case 5:
                printf("Exiting program...\n");
                exit(0);
                
            default:
                printf("Invalid choice! Please try again.\n");
        }
    }
    
    return 0;
}