#include #include #include typedef struct node { int val; struct node *par; struct node *left; struct node *right; int color; } Node; // Create a new node Node *newNode(int val, Node *par) { Node *create = (Node *)(malloc(sizeof(Node))); create->val = val; create->par = par; create->left = NULL; create->right = NULL; create->color = 1; } // Check if the node is the leaf int isLeaf(Node *n) { if (n->left == NULL && n->right == NULL) { return 1; } return 0; } // Left Rotate Node *leftRotate(Node *node) { Node *parent = node->par; Node *grandParent = parent->par; parent->right = node->left; if (node->left != NULL) { node->left->par = parent; } node->par = grandParent; parent->par = node; node->left = parent; if (grandParent != NULL) { if (grandParent->right == parent) { grandParent->right = node; } else { grandParent->left = node; } } return node; } // Right Rotate Node *rightRotate(Node *node) { Node *parent = node->par; Node *grandParent = parent->par; parent->left = node->right; if (node->right != NULL) { node->right->par = parent; } node->par = grandParent; parent->par = node; node->right = parent; if (grandParent != NULL) { if (grandParent->right == parent) { grandParent->right = node; } else { grandParent->left = node; } } return node; } // Check the node after the insertion step void checkNode(Node *node) { // If the node is the root if (node == NULL || node->par == NULL) { return; } Node *child = node; // If it is a black node or its parent is a black node if (node->color == 0 || (node->par)->color == 0) { // Dont Do Anything return; } // Both parent and child are red // Check For Uncle Node *parent = node->par; Node *grandParent = parent->par; // If grandParent is NULL, then parent is the root. // Just make the root black. if (grandParent == NULL) { parent->color = 0; return; } // If both the children of the grandParent are red if (grandParent->right != NULL && (grandParent->right)->color == 1 && grandParent->left != NULL && (grandParent->left)->color == 1) { // Make the grandParent red and both of its children black (grandParent->right)->color = 0; (grandParent->left)->color = 0; grandParent->color = 1; return; } else { // The only option left is rotation. Node *greatGrandParent = grandParent->par; // Right Case if (grandParent->right == parent) { // Right Right Case if (parent->right == node) { grandParent->right = parent->left; if (parent->left != NULL) { (parent->left)->par = grandParent; } parent->left = grandParent; grandParent->par = parent; // Attach to existing Tree; parent->par = greatGrandParent; if (greatGrandParent != NULL) { if (greatGrandParent->left != NULL && greatGrandParent->left == grandParent) { greatGrandParent->left = parent; } else { greatGrandParent->right = parent; } } // Change the colors parent->color = 0; grandParent->color = 1; } else { // Right Left Case // First step -> Parent Child Rotation parent->left = child->right; if (child->right != NULL) { (child->right)->par = parent; } child->right = parent; parent->par = child; // Second step -> Child and GrandParent Rotation grandParent->right = child->left; if (child->left != NULL) { (child->left)->par = grandParent; } child->left = grandParent; grandParent->par = child; // Attach to the existing tree child->par = greatGrandParent; if (greatGrandParent != NULL) { if (greatGrandParent->left != NULL && greatGrandParent->left == grandParent) { greatGrandParent->left = child; } else { greatGrandParent->right = child; } } // Change The Colors child->color = 0; grandParent->color = 1; } } else { // Left Case // Left Left Case if (parent->left == node) { grandParent->left = parent->right; if (parent->right != NULL) { (parent->right)->par = grandParent; } parent->right = grandParent; grandParent->par = parent; // Attach to existing Tree; parent->par = greatGrandParent; if (greatGrandParent != NULL) { if (greatGrandParent->left != NULL && greatGrandParent->left == grandParent) { greatGrandParent->left = parent; } else { greatGrandParent->right = parent; } } // Change the colors parent->color = 0; grandParent->color = 1; } else { // Left Right Case // First step -> Parent Child Rotation parent->right = child->left; if (child->left != NULL) { (child->left)->par = parent; } child->left = parent; parent->par = child; // Second step -> Child and GrandParent Rotation grandParent->left = child->right; if (child->right != NULL) { (child->right)->par = grandParent; } child->right = grandParent; grandParent->par = child; // Attach to the existing tree child->par = greatGrandParent; if (greatGrandParent != NULL) { if (greatGrandParent->left != NULL && greatGrandParent->left == grandParent) { greatGrandParent->left = child; } else { greatGrandParent->right = child; } } // Change The Colors child->color = 0; grandParent->color = 1; } } } } // To insert a node in the existing tree void insertNode(int val, Node **root) { Node *buffRoot = *root; while (buffRoot) { if (buffRoot->val > val) { // Go left if (buffRoot->left != NULL) { buffRoot = buffRoot->left; } else { // Insert The Node Node *toInsert = newNode(val, buffRoot); buffRoot->left = toInsert; buffRoot = toInsert; // Check For Double Red Problems break; } } else { // Go right if (buffRoot->right != NULL) { buffRoot = buffRoot->right; } else { // Insert The Node Node *toInsert = newNode(val, buffRoot); buffRoot->right = toInsert; buffRoot = toInsert; // Check For Double Red Problems break; } } } while (buffRoot != *root) { checkNode(buffRoot); if (buffRoot->par == NULL) { *root = buffRoot; break; } buffRoot = buffRoot->par; if (buffRoot == *root) { buffRoot->color = 0; } } } void checkForCase2(Node *toDelete, int delete, int fromDirection, Node **root) { if (toDelete == (*root)) { (*root)->color = 0; return; } if (!delete &&toDelete->color == 1) { if (!fromDirection) { if (toDelete->right != NULL) { toDelete->right->color = 1; } } else { if (toDelete->left != NULL) { toDelete->left->color = 1; } } toDelete->color = 0; return; } // Get the sibling for further inspection Node *sibling; Node *parent = toDelete->par; int locateChild = 0; // 0 if toDeleted is left of its parent else 1 if (parent->right == toDelete) { sibling = parent->left; locateChild = 1; } else { sibling = parent->right; } // Case 2.1. i.e. if the any children of the sibling is red if ((sibling->right != NULL && sibling->right->color == 1) || (sibling->left != NULL && sibling->left->color == 1)) { if (sibling->right != NULL && sibling->right->color == 1) { // Sibling is left and child is right. i.e. LEFT RIGHT ROTATION if (locateChild == 1) { int parColor = parent->color; // Step 1: Left rotate sibling sibling = leftRotate(sibling->right); // Step 2: Right rotate updated sibling parent = rightRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } // Step 3: Update the colors parent->color = parColor; parent->left->color = 0; parent->right->color = 0; // Delete the node (present at parent->right->right) if (delete) { if (toDelete->left != NULL) { toDelete->left->par = parent->right; } parent->right->right = toDelete->left; free(toDelete); } } else { // Sibling is right and child is also right. i.e. LEFT LEFT // ROTATION int parColor = parent->color; // Left Rotate the sibling parent = leftRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } // Update Colors parent->color = parColor; parent->left->color = 0; parent->right->color = 0; // Delete the node (present at parent->left->left) if (delete) { if (toDelete->right != NULL) { toDelete->right->par = parent->left; } parent->left->left = toDelete->left; free(toDelete); } } } else { // Sibling is right and child is left. i.e. RIGHT LEFT ROTATION if (locateChild == 0) { int parColor = parent->color; // Step 1: Right rotate sibling sibling = rightRotate(sibling->left); // printf("%d - reached\n", sibling->val); // return; // Step 2: Left rotate updated sibling parent = leftRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } // Step 3: Update the colors parent->color = parColor; parent->left->color = 0; parent->right->color = 0; // Delete the node (present at parent->left->left) if (delete) { if (toDelete->right != NULL) { toDelete->right->par = parent->left; } parent->left->left = toDelete->right; free(toDelete); } } else { // Sibling is left and child is also left. i.e. RIGHT RIGHT // ROTATION int parColor = parent->color; // Right Rotate the sibling parent = rightRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } // Update Colors parent->color = parColor; parent->left->color = 0; parent->right->color = 0; // Delete the node (present at parent->right->right) if (delete) { if (toDelete->left != NULL) { toDelete->left->par = parent->right; } parent->right->right = toDelete->left; free(toDelete); } } } } else if (sibling->color == 0) { // Make the sibling red and recur for its parent // Recolor the sibling sibling->color = 1; // Delete if necessary if (delete) { if (locateChild) { toDelete->par->right = toDelete->left; if (toDelete->left != NULL) { toDelete->left->par = toDelete->par; } } else { toDelete->par->left = toDelete->right; if (toDelete->right != NULL) { toDelete->right->par = toDelete->par; } } } checkForCase2(parent, 0, locateChild, root); } else { // Bring the sibling on top and apply 2.1 or 2.2 accordingly if (locateChild) { // Right Rotate toDelete->par->right = toDelete->left; if (toDelete->left != NULL) { toDelete->left->par = toDelete->par; } parent = rightRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } parent->color = 0; parent->right->color = 1; checkForCase2(parent->right, 0, 1, root); } else { // Left Rotate toDelete->par->left = toDelete->right; if (toDelete->right != NULL) { toDelete->right->par = toDelete->par; } parent = leftRotate(sibling); // Check if the root is rotated if (parent->par == NULL) { *root = parent; } printf("\nroot - %d - %d\n", parent->val, parent->left->val); parent->color = 0; parent->left->color = 1; checkForCase2(parent->left, 0, 0, root); } } } // To delete a node from the tree void deleteNode(int val, Node **root) { Node *buffRoot = *root; // Search for the element in the tree while (1) { if (val == buffRoot->val) { // Node Found break; } if (val > buffRoot->val) { if (buffRoot->right != NULL) { buffRoot = buffRoot->right; } else { printf("Node Not Found!!!"); return; } } else { if (buffRoot->left != NULL) { buffRoot = buffRoot->left; } else { printf("Node Not Found!!!"); return; } } } Node *toDelete = buffRoot; // Look for the leftmost of right node or right most of left node if (toDelete->left != NULL) { toDelete = toDelete->left; while (toDelete->right != NULL) { toDelete = toDelete->right; } } else if (toDelete->right != NULL) { toDelete = toDelete->right; while (toDelete->left != NULL) { toDelete = toDelete->left; } } if (toDelete == *root) { *root = NULL; return; } // Swap the values buffRoot->val = toDelete->val; toDelete->val = val; // Checking for case 1 if (toDelete->color == 1 || (toDelete->left != NULL && toDelete->left->color == 1) || (toDelete->right != NULL && toDelete->right->color == 1)) { // if it is a leaf if (toDelete->left == NULL && toDelete->right == NULL) { // Delete instantly if (toDelete->par->left == toDelete) { toDelete->par->left = NULL; } else { toDelete->par->right = NULL; } } else { // else its child should be red // Check for the exitstence of left node if (toDelete->left != NULL) { // The node should be right to its parent toDelete->par->right = toDelete->left; toDelete->left->par = toDelete->par; toDelete->left->color = 1; } else { // else the right node should be red toDelete->par->left = toDelete->right; toDelete->right->par = toDelete->par; toDelete->right->color = 1; } } // Remove the node from memory free(toDelete); } else { // Case 2 checkForCase2(toDelete, 1, ((toDelete->par->right == toDelete)), root); } } void printInorder(Node *root) { if (root != NULL) { printInorder(root->left); printf("%d c-%d ", root->val, root->color); printInorder(root->right); } } void checkBlack(Node *temp, int c) { if (temp == NULL) { printf("%d ", c); return; } if (temp->color == 0) { c++; } checkBlack(temp->left, c); checkBlack(temp->right, c); } int main() { Node *root = NULL; int scanValue, choice = 1; printf( "1 - Input\n2 - Delete\n3 - Inorder Traversel\n0 - Quit\n\nPlease " "Enter the Choice - "); scanf("%d", &choice); while (choice) { switch (choice) { case 1: printf("\n\nPlease Enter A Value to insert - "); scanf("%d", &scanValue); if (root == NULL) { root = newNode(scanValue, NULL); root->color = 0; } else { insertNode(scanValue, &root); } printf("\nSuccessfully Inserted %d in the tree\n\n", scanValue); break; case 2: printf("\n\nPlease Enter A Value to Delete - "); scanf("%d", &scanValue); deleteNode(scanValue, &root); printf("\nSuccessfully Inserted %d in the tree\n\n", scanValue); break; case 3: printf("\nInorder Traversel - "); printInorder(root); printf("\n\n"); // checkBlack(root,0); // printf("\n"); break; default: if (root != NULL) { printf("Root - %d\n", root->val); } } printf( "1 - Input\n2 - Delete\n3 - Inorder Traversel\n0 - " "Quit\n\nPlease Enter the Choice - "); scanf("%d", &choice); } } // 32 12 50 53 1 2 3 4 5 6 7 8 9