static void rotate_right(rb_tree__t* tree, rb_node__t* node){ assert(node != NULL && node->left != NULL); rb_node__t* p = node; rb_node__t* q = node->left; rb_node__t* parent = node->parent; if (!rb_is_root(p)){ if (parent->left == p) parent->left = q; else parent->right = q; } else tree->root = q; q->parent = parent; p->parent = q; p->left = q->right; if (NULL != p->left) p->left->parent = p; q->right = p; }
static void rb_rotate_right(char *node, char **tree) { char *p = node; char *q = rbtree_get_left(node); /* can't be NULL */ char *parent = rb_get_parent(p); if (!rb_is_root(p)) { if (rbtree_get_left(parent) == p) rb_set_left(q, parent); else rb_set_right(q, parent); } else *tree = q; rb_set_parent(parent, q); rb_set_parent(q, p); rb_set_left(rbtree_get_right(q), p); if (rbtree_get_left(p)) rb_set_parent(p, rbtree_get_left(p)); rb_set_right(p, q); }
/*Insert item to tree return NULL is malloc fail if duplicate item is found, return the node address of duplicate item, otherwise return new node address*/ rb_node__t* rb_insert__r(rb_tree__t* tree, const void* item){ rb_node__t* node; rb_node__t* node_new; rb_node__t* p; /*Traverse iterator*/ rb_node__t* parent = NULL; int is_left = 0; assert(tree != NULL && item != NULL); p = tree->root; while(p != NULL){ int cmp_result = tree->compare(item, p->item); if(cmp_result == 0) { return p; } parent = p; if (cmp_result < 0){ is_left = 1; p = p->left; }else{ is_left = 0; p = p->right; } } node_new = new_node(item, RB_RED, NULL, NULL, parent, tree->new_item); if (node_new == NULL) return NULL; node = node_new; if((parent != NULL)&&(!rb_is_root(node))){ if(is_left) parent->left = node; else parent->right = node; } else{ tree->root = node; } while(parent != NULL && parent->color == RB_RED){ rb_node__t* grandpa = parent->parent; rb_node__t* uncle; if( grandpa == NULL) break; if(grandpa->left == parent){ uncle = grandpa->right; if(uncle && uncle->color == RB_RED){ parent->color = RB_BLACK; uncle->color = RB_BLACK; grandpa->color = RB_RED; node = grandpa; } else{ if(node == parent->right){ rotate_left(tree, parent); node = parent; parent = node->parent; } parent->color = RB_BLACK; grandpa->color = RB_RED; rotate_right(tree, grandpa); } } else{ uncle = grandpa->left; if(uncle && uncle->color == RB_RED){ parent->color = RB_BLACK; uncle->color = RB_BLACK; grandpa->color = RB_RED; node = grandpa; } else{ if(node == parent->left){ rotate_right(tree, parent); node = parent; parent = node->parent; } parent->color = RB_BLACK; grandpa->color = RB_RED; rotate_left(tree, grandpa); } } parent = node->parent; } tree->root->color = RB_BLACK; tree->node_num++; return node_new; }