/* insert may violate the rbtree properties, fix up the tree */ void rbtree_insert_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node) { util_rbtree_node_t *p, *u; /* u is the uncle node of node */ while(util_rbt_isred(node->parent) && (node !=rbtree->root )) { p = node->parent; if(p == p->parent->left) /* parent is the left child */ { u = p->parent->right; if(util_rbt_isred(u)) /* case 1: p & u are red */ { util_rbt_black(u); util_rbt_black(p); util_rbt_red(p->parent); node = p->parent; } else { if(node == p->right) /* case 2: p:read, u:black, node is right child */ { node = p; rbtree_left_rotate(rbtree, node); p = node->parent; } /* case 3: p:read, u:black, node is left child */ util_rbt_black(p); util_rbt_red(p->parent); rbtree_right_rotate(rbtree, p->parent); } } else /* parent is the right child */ { u = p->parent->left; if(util_rbt_isred(u)) { util_rbt_black(u); util_rbt_black(p); util_rbt_red(p->parent); node = p->parent; } else { if(p->left == node) { node = p; rbtree_right_rotate(rbtree, node); p = node->parent; } util_rbt_black(p); util_rbt_red(p->parent); rbtree_left_rotate(rbtree, p->parent); } } } /* mark root to black */ util_rbt_black(rbtree->root); }
static void rbtree_remove_fixup(rbtree_t *tree, rbtree_node_t *node) { rbtree_node_t *brother; while (node != tree->root && rbtree_is_black(node)) { if (node == node->parent->left) { brother = node->parent->right; if (rbtree_is_red(brother)) { rbtree_color_swap(node->parent, brother); rbtree_left_rotate(tree, node->parent); brother = node->parent->right; } if (rbtree_is_black(brother->left) && rbtree_is_black(brother->right)) { rbtree_set_red(brother); node = node->parent; } else { if (rbtree_is_black(brother->right)) { rbtree_color_swap(brother, brother->left); rbtree_right_rotate(tree, brother); brother = node->parent->right; } rbtree_set_black(brother->right); rbtree_color_swap(node->parent, brother); rbtree_left_rotate(tree, node->parent); node = tree->root; } } else { brother = node->parent->left; if (rbtree_is_red(brother)) { rbtree_color_swap(node->parent, brother); rbtree_right_rotate(tree, node->parent); brother = node->parent->left; } if (rbtree_is_black(brother->left) && rbtree_is_black(brother->right)) { rbtree_set_red(brother); node = node->parent; } else { if (rbtree_is_black(brother->left)) { rbtree_color_swap(brother, brother->right); rbtree_left_rotate(tree, brother); brother = node->parent->left; } rbtree_set_black(brother->left); rbtree_color_swap(node->parent, brother); rbtree_right_rotate(tree, node->parent); node = tree->root; } } } rbtree_set_black(node); }
void rbtree_insert(volatile rbtree_t *tree,rbtree_node_t *node){ rbtree_node_t **root,*temp,*sentinel; root = (rbtree_node_t **)&tree -> root; sentinel = tree -> sentinel; if(*root == sentinel){ node -> parent = NULL; node -> left = sentinel; node -> right = sentinel; rbt_black(node); *root = node; return; } tree -> insert(*root,node,sentinel); /*re_balance tree*/ while(node != *root && rbt_is_red(node -> parent)){ if(node -> parent == node -> parent -> parent -> left){ temp = node -> parent -> parent -> right; if(rbt_is_red(temp)){ rbt_black(node -> parent); rbt_black(temp); rbt_red(node -> parent -> parent); node = node -> parent -> parent; }else{ if(node == node -> parent -> right){ node = node -> parent; rbtree_left_rotate(root,sentinel,node); } rbt_black(node -> parent); rbt_red(node -> parent -> parent); rbtree_right_rotate(root,sentinel,node -> parent -> parent); } }else{ temp = node -> parent -> parent -> left; if(rbt_is_red(temp)){ rbt_black(node -> parent); rbt_black(temp); rbt_red(node -> parent -> parent); node = node -> parent -> parent; }else{ if(node == node -> parent -> left){ node = node -> parent; rbtree_right_rotate(root,sentinel,node); } rbt_black(node -> parent); rbt_red(node -> parent -> parent); rbtree_left_rotate(root,sentinel,node -> parent -> parent); } } } rbt_black(*root); }
static void rbtree_insert_fixup(rbtree_t *tree, rbtree_node_t *node) { while (rbtree_is_red(node->parent)) { if (node->parent == node->parent->parent->left) { if (rbtree_is_red(node->parent->parent->right)) { rbtree_set_black(node->parent); rbtree_set_black(node->parent->parent->right); rbtree_set_red(node->parent->parent); node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rbtree_left_rotate(tree, node); } rbtree_set_black(node->parent); rbtree_set_red(node->parent->parent); rbtree_right_rotate(tree, node->parent->parent); } } else { if (rbtree_is_red(node->parent->parent->left)) { rbtree_set_black(node->parent); rbtree_set_black(node->parent->parent->left); rbtree_set_red(node->parent->parent); } else { if (node == node->parent->left) { node = node->parent; rbtree_right_rotate(tree, node); } rbtree_set_black(node->parent); rbtree_set_red(node->parent->parent); rbtree_left_rotate(tree, node->parent->parent); } } } rbtree_set_black(tree->root); }
void rbtree_delete( rbtree_t *tree , rbtree_node_t *node ) { uint_t red; rbtree_node_t **root,*sentinel,*subst,*temp,*w; /* a binary tree delete */ root = (rbtree_node_t **) &tree->root; sentinel = tree->sentinel; if (node->left == sentinel) { temp = node->right; subst = node; } else if (node->right == sentinel) { temp = node->left; subst = node; } else { subst = rbtree_min( node->right , sentinel ); if (subst->left != sentinel) { temp = subst->left; } else { temp = subst->right; } } if (subst == *root) { *root = temp; rbt_black( temp ); /* DEBUG stuff */ node->left = NULL; node->right = NULL; node->parent = NULL; node->key = 0; return; } red = rbt_is_red(subst); if (subst == subst->parent->left) { subst->parent->left = temp; } else { subst->parent->right = temp; } if (subst == node) { temp->parent = subst->parent; } else { if (subst->parent == node) { temp->parent = subst; } else { temp->parent = subst->parent; } subst->left = node->left; subst->right = node->right; subst->parent = node->parent; rbt_copy_color( subst , node ); if (node == *root) { *root = subst; } else { if (node == node->parent->left) { node->parent->left = subst; } else { node->parent->right = subst; } } if (subst->left != sentinel) { subst->left->parent = subst; } if (subst->right != sentinel) { subst->right->parent = subst; } } /* DEBUG stuff */ node->left = NULL; node->right = NULL; node->parent = NULL; node->key = 0; if (red) { return; } /* a delete fixup */ while (temp != *root && rbt_is_black(temp) ) { if (temp == temp->parent->left) { w = temp->parent->right; if (rbt_is_red(w) ) { rbt_black( w ); rbt_red( temp->parent ); rbtree_left_rotate( root , sentinel , temp->parent ); w = temp->parent->right; } if (rbt_is_black(w->left) && rbt_is_black(w->right) ) { rbt_red( w ); temp = temp->parent; } else { if (rbt_is_black(w->right) ) { rbt_black( w->left ); rbt_red( w ); rbtree_right_rotate( root , sentinel , w ); w = temp->parent->right; } rbt_copy_color( w , temp->parent ); rbt_black( temp->parent ); rbt_black( w->right ); rbtree_left_rotate( root , sentinel , temp->parent ); temp = *root; } } else { w = temp->parent->left; if (rbt_is_red(w) ) { rbt_black( w ); rbt_red( temp->parent ); rbtree_right_rotate( root , sentinel , temp->parent ); w = temp->parent->left; } if (rbt_is_black(w->left) && rbt_is_black(w->right) ) { rbt_red( w ); temp = temp->parent; } else { if (rbt_is_black(w->left) ) { rbt_black( w->right ); rbt_red( w ); rbtree_left_rotate( root , sentinel , w ); w = temp->parent->left; } rbt_copy_color( w , temp->parent ); rbt_black( temp->parent ); rbt_black( w->left ); rbtree_right_rotate( root , sentinel , temp->parent ); temp = *root; } } } rbt_black( temp ); }
struct rbtree *rbtree_fixup_add(struct rbtree *root, struct rbtree *node) { struct rbtree *uncle; //Текущий узел красного цвета(RED) while (node != root && node -> parent -> color == COLOR_RED) { if (node -> parent == node -> parent -> parent ->left) { //Узел в дереве слева дедушки uncle = node -> parent -> parent -> right; if (uncle -> color == COLOR_RED){ // Шаг 1 - Дядя Красный (RED) node -> parent ->color = COLOR_BLACK; uncle -> color = COLOR_BLACK; node -> parent -> parent -> color = COLOR_RED; node = node -> parent -> parent; } else { // Шаг 2-3 - Дядя Черный (BLACK) if (node == node -> parent -> right){ //возаврат назад на шаги 2-3 node = node -> parent; root = rbtree_left_rotate(root, node -> parent -> parent); } // Шаг 3 node -> parent -> color = COLOR_BLACK; node -> parent -> parent -> color = COLOR_RED; root = rbtree_right_rotate(root, node -> parent -> parent); } } else { /* Узел в правом дереве деда * Шаги 4-5-6 * Узел в правом дереве деда */ uncle = node -> parent -> parent -> left; if (uncle -> color == COLOR_RED){ // Дядя является красным - Шаг 4 node -> parent -> color = COLOR_BLACK; uncle -> color = COLOR_BLACK; node -> parent -> parent -> color = COLOR_RED; node = node -> parent -> parent; }else { // Дядя черный if (node == node -> parent ->left){ node = node -> parent; root = rbtree_right_rotate(root, node); } node -> parent -> color = COLOR_BLACK; node -> parent -> parent -> color = COLOR_RED; root = rbtree_left_rotate(root, node -> parent -> parent); } } } root -> color = COLOR_BLACK; return root; }
void rbtree_delete(struct rbtree *tree, struct rbnode *node) { struct rbnode **root = &tree->root; struct rbnode *sentinel = tree->sentinel; struct rbnode *subst, *temp, *w; uint8_t red; /* a binary tree delete */ if (node->left == sentinel) { temp = node->right; subst = node; } else if (node->right == sentinel) { temp = node->left; subst = node; } else { subst = rbtree_node_min(node->right, sentinel); if (subst->left != sentinel) { temp = subst->left; } else { temp = subst->right; } } if (subst == *root) { *root = temp; rbtree_black(temp); rbtree_node_init(node); return; } red = rbtree_is_red(subst); if (subst == subst->parent->left) { subst->parent->left = temp; } else { subst->parent->right = temp; } if (subst == node) { temp->parent = subst->parent; } else { if (subst->parent == node) { temp->parent = subst; } else { temp->parent = subst->parent; } subst->left = node->left; subst->right = node->right; subst->parent = node->parent; rbtree_copy_color(subst, node); if (node == *root) { *root = subst; } else { if (node == node->parent->left) { node->parent->left = subst; } else { node->parent->right = subst; } } if (subst->left != sentinel) { subst->left->parent = subst; } if (subst->right != sentinel) { subst->right->parent = subst; } } rbtree_node_init(node); if (red) { return; } /* a delete fixup */ while (temp != *root && rbtree_is_black(temp)) { if (temp == temp->parent->left) { w = temp->parent->right; if (rbtree_is_red(w)) { rbtree_black(w); rbtree_red(temp->parent); rbtree_left_rotate(root, sentinel, temp->parent); w = temp->parent->right; } if (rbtree_is_black(w->left) && rbtree_is_black(w->right)) { rbtree_red(w); temp = temp->parent; } else { if (rbtree_is_black(w->right)) { rbtree_black(w->left); rbtree_red(w); rbtree_right_rotate(root, sentinel, w); w = temp->parent->right; } rbtree_copy_color(w, temp->parent); rbtree_black(temp->parent); rbtree_black(w->right); rbtree_left_rotate(root, sentinel, temp->parent); temp = *root; } } else { w = temp->parent->left; if (rbtree_is_red(w)) { rbtree_black(w); rbtree_red(temp->parent); rbtree_right_rotate(root, sentinel, temp->parent); w = temp->parent->left; } if (rbtree_is_black(w->left) && rbtree_is_black(w->right)) { rbtree_red(w); temp = temp->parent; } else { if (rbtree_is_black(w->left)) { rbtree_black(w->right); rbtree_red(w); rbtree_left_rotate(root, sentinel, w); w = temp->parent->left; } rbtree_copy_color(w, temp->parent); rbtree_black(temp->parent); rbtree_black(w->left); rbtree_right_rotate(root, sentinel, temp->parent); temp = *root; } } } rbtree_black(temp); }
void rbtree_insert(struct rbtree *tree, struct rbnode *node) { struct rbnode **root = &tree->root; struct rbnode *sentinel = tree->sentinel; struct rbnode *temp, **p; /* empty tree */ if (*root == sentinel) { node->parent = NULL; node->left = sentinel; node->right = sentinel; rbtree_black(node); *root = node; return; } /* a binary tree insert */ temp = *root; for (;;) { p = (node->key < temp->key) ? &temp->left : &temp->right; if (*p == sentinel) { break; } temp = *p; } *p = node; node->parent = temp; node->left = sentinel; node->right = sentinel; rbtree_red(node); /* re-balance tree */ while (node != *root && rbtree_is_red(node->parent)) { if (node->parent == node->parent->parent->left) { temp = node->parent->parent->right; if (rbtree_is_red(temp)) { rbtree_black(node->parent); rbtree_black(temp); rbtree_red(node->parent->parent); node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rbtree_left_rotate(root, sentinel, node); } rbtree_black(node->parent); rbtree_red(node->parent->parent); rbtree_right_rotate(root, sentinel, node->parent->parent); } } else { temp = node->parent->parent->left; if (rbtree_is_red(temp)) { rbtree_black(node->parent); rbtree_black(temp); rbtree_red(node->parent->parent); node = node->parent->parent; } else { if (node == node->parent->left) { node = node->parent; rbtree_right_rotate(root, sentinel, node); } rbtree_black(node->parent); rbtree_red(node->parent->parent); rbtree_left_rotate(root, sentinel, node->parent->parent); } } } rbtree_black(*root); }
/* delete may violate the rbtree properties, fix up the tree */ void rbtree_delete_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node) { int h = 0; util_rbtree_node_t *w; while((node != rbtree->root) && util_rbt_isblack(node)) { h++; if(node == node->parent->left) /* node is left child */ { w = node->parent->right; if(util_rbt_isred(w)) { util_rbt_black(w); util_rbt_red(node->parent); rbtree_left_rotate(rbtree, node->parent); w = node->parent->right; } if(util_rbt_isblack(w->left) && util_rbt_isblack(w->right)) { util_rbt_red(w); node = node->parent; } else { if(util_rbt_isblack(w->right)) { util_rbt_black(w->left); util_rbt_red(w); rbtree_right_rotate(rbtree, w); w = node->parent->right; } w->color = node->parent->color; util_rbt_black(node->parent); util_rbt_black(w->right); rbtree_left_rotate(rbtree, node->parent); node = rbtree->root; /* to break loop */ } } else /* node is right child */ { w = node->parent->left; if(w == 0) { //FIXME: //int t = 4; } if(util_rbt_isred(w)) { util_rbt_black(w); util_rbt_red(node->parent); rbtree_right_rotate(rbtree, node->parent); w = node->parent->left; } if(util_rbt_isblack(w->left) && util_rbt_isblack(w->right)) { util_rbt_red(w); node = node->parent; } else { if(util_rbt_isblack(w->left)) { util_rbt_black(w->right); util_rbt_red(w); rbtree_left_rotate(rbtree, w); w = node->parent->left; } w->color = node->parent->color; util_rbt_black(node->parent); util_rbt_black(w->left); rbtree_right_rotate(rbtree, node->parent); node = rbtree->root; /* to break loop */ } } } util_rbt_black(node); }
void rbtree_insert(ezRBTree *tree, ezRBTreeNode *node) { ezRBTreeNode **root, *temp, *sentinel; /* a binary tree insert */ root = (ezRBTreeNode **) &tree->root; sentinel = tree->sentinel; if (*root == sentinel) { node->parent = NULL; node->left = sentinel; node->right = sentinel; rbt_black(node); *root = node; return; } default_rbtree_insert_value(tree, *root, node, sentinel); /* re-balance tree */ while (node != *root && rbt_is_red(node->parent)) { if (node->parent == node->parent->parent->left) { temp = node->parent->parent->right; if (rbt_is_red(temp)) { rbt_black(node->parent); rbt_black(temp); rbt_red(node->parent->parent); node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rbtree_left_rotate(root, sentinel, node); } rbt_black(node->parent); rbt_red(node->parent->parent); rbtree_right_rotate(root, sentinel, node->parent->parent); } } else { temp = node->parent->parent->left; if (rbt_is_red(temp)) { rbt_black(node->parent); rbt_black(temp); rbt_red(node->parent->parent); node = node->parent->parent; } else { if (node == node->parent->left) { node = node->parent; rbtree_right_rotate(root, sentinel, node); } rbt_black(node->parent); rbt_red(node->parent->parent); rbtree_left_rotate(root, sentinel, node->parent->parent); } } } rbt_black(*root); }
/* * 红黑树删除修正函数 * * 在从红黑树中删除插入节点之后(红黑树失去平衡),再调用该函数; * 目的是将它重新塑造成一颗红黑树。 * * 参数说明: * root 红黑树的根 * node 待修正的节点 */ static void rbtree_delete_fixup(RBRoot *root, Node *node, Node *parent) { Node *other; while ((!node || rb_is_black(node)) && node != root->node) { if (parent->left == node) { //1. parent parent.r old.ohter.b // / \ / \ / \ // child.b other.r child.b other.b parent.r d // / \ / \ / \ / \ / \ // a b c d a b c d child.b c <- new.other // / \ // a b other = parent->right; if (rb_is_red(other)) { // Case 1: x的兄弟w是红色的 rb_set_black(other); rb_set_red(parent); rbtree_left_rotate(root, parent); other = parent->right; } //2. gparent gparent 3. <- new.parent // | // parent parent 2. <- new.child // / \ / \ // child.b other old.child.b other.r 1. <- color = RED // / \ / \ // a b c.b d.b if ((!other->left || rb_is_black(other->left)) && (!other->right || rb_is_black(other->right))) { // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的 rb_set_red(other); node = parent; parent = rb_parent(node); } else { if (!other->right || rb_is_black(other->right)) { //3.1 parent parent parent // / \ / \ / \ // child.b other.b child.b other.r <- color RED child.b c.b <- new.other // / \ / \ / \ / \ / \ \ // a b c d.b a b c.b d.b <- c.color BLACK a b old.other.r // / \ // d.b // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。 rb_set_black(other->left); rb_set_red(other); rbtree_right_rotate(root, other); other = parent->right; } //3.2 parent.c parent.b 2<- color BLACK other.b // / \ / \ / \ // child.b other.b child.b other.c 1<- color parent.color parent.b d.b // / \ / \ / \ / \ / \ // a b c d.r a b c d.b 3<- color BLACK child.b c // / \ // a b // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。 rb_set_color(other, rb_color(parent)); rb_set_black(parent); rb_set_black(other->right); rbtree_left_rotate(root, parent); node = root->node; break; } } else { other = parent->left; if (rb_is_red(other)) { // Case 1: x的兄弟w是红色的 rb_set_black(other); rb_set_red(parent); rbtree_right_rotate(root, parent); other = parent->left; } if ((!other->left || rb_is_black(other->left)) && (!other->right || rb_is_black(other->right))) { // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的 rb_set_red(other); node = parent; parent = rb_parent(node); } else { if (!other->left || rb_is_black(other->left)) { // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。 rb_set_black(other->right); rb_set_red(other); rbtree_left_rotate(root, other); other = parent->left; } // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。 rb_set_color(other, rb_color(parent)); rb_set_black(parent); rb_set_black(other->left); rbtree_right_rotate(root, parent); node = root->node; break; } } } if (node) rb_set_black(node); }
/* * 红黑树插入修正函数 * * 在向红黑树中插入节点之后(失去平衡),再调用该函数; * 目的是将它重新塑造成一颗红黑树。 * * 参数说明: * root 红黑树的根 * node 插入的结点 // 对应《算法导论》中的z */ static void rbtree_insert_fixup(RBRoot *root, Node *node) { Node *parent, *gparent; // 若“父节点存在,并且父节点的颜色是红色” while ((parent = rb_parent(node)) && rb_is_red(parent)) { gparent = rb_parent(parent); //若“父节点”是“祖父节点的左孩子” if (parent == gparent->left) { // Case 1条件:叔叔节点是红色 { Node *uncle = gparent->right; if (uncle && rb_is_red(uncle)) { rb_set_black(uncle); rb_set_black(parent); rb_set_red(gparent); node = gparent; continue; } } // Case 2条件:叔叔是黑色,且当前节点是右孩子 if (parent->right == node) { Node *tmp; rbtree_left_rotate(root, parent); tmp = parent; parent = node; node = tmp; } // Case 3条件:叔叔是黑色,且当前节点是左孩子。 rb_set_black(parent); rb_set_red(gparent); rbtree_right_rotate(root, gparent); } else//若“z的父节点”是“z的祖父节点的右孩子” { // Case 1条件:叔叔节点是红色 { Node *uncle = gparent->left; if (uncle && rb_is_red(uncle)) { rb_set_black(uncle); rb_set_black(parent); rb_set_red(gparent); node = gparent; continue; } } // Case 2条件:叔叔是黑色,且当前节点是左孩子 if (parent->left == node) { Node *tmp; rbtree_right_rotate(root, parent); tmp = parent; parent = node; node = tmp; } // Case 3条件:叔叔是黑色,且当前节点是右孩子。 rb_set_black(parent); rb_set_red(gparent); rbtree_left_rotate(root, gparent); } } // 将根节点设为黑色 rb_set_black(root->node); }