Esempio n. 1
0
void insert(struct node **root, int key)
{
	struct node *z;
	z = bst_insert(root, key);
	z->color = RED;
	fix_rb_tree(root, z);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/*
* 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;
}