void insert(struct node **root, int key) { struct node *z; z = bst_insert(root, key); z->color = RED; fix_rb_tree(root, z); }
void insert( const char *name ) { debug("Insert node: %s", name); // Is name exceeding MAX_NAME_LENGTH chars? unsigned int len = strlen(name); // MAX_NAME_LENGTH is 59 bytes+'\0' check(len<MAX_NAME_LENGTH, "Insert: Name exceeds maximal length."); // Allocate and initialize a new node Node *n = malloc(sizeof(Node)); check_mem(n); n->parent = NULL; n->left = NIL; n->right = NIL; n->color = RED; strncpy(n->name, name, len); n->name[len] = '\0'; if(root == NULL) { ins_count = 0; dbl_count = 0; del_count = 0; root = n; } else { // if already exsits skip if(find_by_name(n->name)) { debug("Insert node: %salready exists", n->name); dbl_count++; free(n); return; } // search for the proper place to include the node Node *current = root; while (1) { // debug("Cmp %s with %s", n->name, current->name); int res = strcmp(n->name, current->name); if(res < 0) { if(current->left == NIL) { current->left = n; n->parent = current; break; } else { current = current->left; } } else if(res > 0) { if(current->right == NIL) { current->right = n; n->parent = current; break; } else { current = current->right; } } } } // ensure red black tree properties fix_rb_tree(n); ins_count++; debug("Insert Counter: %d\n", ins_count); // check for properties check_requirements(root); error: return; }
/* * An inserted node is always red. This violates maybe req. 2.) --> repairing necessary * Given a Node N to be inserted, it's Uncle (U), it's parent (P) and grandparent (GP), * five cases have to be considered: * 1.) root == NULL, (obvious) * 2.) The parent of N is black -> nothing to do * 3.) U and P of N is red -> color U,P black and GP red. -> req. 2.) maybe violated * then recursivley insert GP to the tree * 4.) N has non or a black U while N is the right child of his red P and P is left of GP * -> left rotation around P and apply case 5.) * 5.) N has non or a black U and is the left child of his red P and P is left of GP. * -> right rotation around GP. Then swap colors of former GP and P. */ void fix_rb_tree( Node *n ) { check(n, "Insert node: new_node == NULL"); Node *parent = n->parent; // case 1.) if(parent == NULL) { // debug("Insert node: case 1.)"); n->color = BLACK; return; } // case 2.) The parent is black. There is no need to fix the tree. if(parent->color == BLACK) { // debug("Insert node: case 2.)"); return; } // case 3.) U and P of N is red -> color U,P black and GP red. if(uncle(n)->color == RED) { // debug("Insert node: case 3.)"); n->parent->color = BLACK; uncle(n)->color = BLACK; grandparent(n)->color = RED; fix_rb_tree(grandparent(n)); return; } // case 4.) N has non or a black U while N is the right child of his red P and P is left of GP if( n == n->parent->right && n->parent == grandparent(n)->left ) { // debug("Fixing: case 4.) rotate left."); rotate_left(n->parent); n = n->left; } else if( n == n->parent->left && n->parent == grandparent(n)->right) { // debug("Fixing: case 4.) rotate right."); rotate_right(n->parent); n = n->right; } // 5.) N has non or a black U and is the left child of his red P and P is left of GP. n->parent->color = BLACK; grandparent(n)->color = RED; if( n == n->parent->left && n->parent == grandparent(n)->left ) { // debug("Fixing: case 5.) rotate right."); rotate_right(grandparent(n)); } else { // debug("Fixing: case 5.) rotate left."); rotate_left(grandparent(n)); } error: return; }