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); }
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 ); }
/****************************************************************************** **函数名称: rbt_delete_fixup **功 能: 修复删除操作造成的黑红树性质的破坏(内部接口) **输入参数: ** tree: 红黑树 ** node: 实际被删结点的替代结点(注: node有可能是叶子结点) **输出参数: NONE **返 回: RBT_OK:成功 RBT_ERR:失败 **实现描述: **注意事项: 被删结点为黑色结点,才能调用此函数进行性质调整 **作 者: # Qifeng.zou # 2013.12.28 # ******************************************************************************/ static int rbt_delete_fixup(rbt_tree_t *tree, rbt_node_t *node) { rbt_node_t *parent = NULL, *brother = NULL; while (rbt_is_black(node) && (tree->root != node)) { /* Set parent and brother */ parent = node->parent; if (node == parent->lchild) { brother = parent->rchild; /* Case 1: 兄弟结点为红色: 以parent为支点, 左旋处理 */ if (rbt_is_red(brother)) { rbt_set_red(parent); rbt_set_black(brother); rbt_left_rotate(tree, parent); /* 参照结点node不变, 兄弟结点改为parent->rchild */ brother = parent->rchild; /* 注意: 此时处理还没有结束,还需要做后续的调整处理 */ } /* Case 2: 兄弟结点为黑色(默认), 且兄弟结点的2个子结点都为黑色 */ if (rbt_is_black(brother->lchild) && rbt_is_black(brother->rchild)) { rbt_set_red(brother); node = parent; } else { /* Case 3: 兄弟结点为黑色(默认), 兄弟节点的左子结点为红色, 右子结点为黑色: 以brother为支点, 右旋处理 */ if (rbt_is_black(brother->rchild)) { rbt_set_black(brother->lchild); rbt_set_red(brother); rbt_right_rotate(tree, brother); /* 参照结点node不变 */ brother = parent->rchild; } /* Case 4: 兄弟结点为黑色(默认), 兄弟结点右孩子结点为红色: 以parent为支点, 左旋处理 */ rbt_copy_color(brother, parent); rbt_set_black(brother->rchild); rbt_set_black(parent); rbt_left_rotate(tree, parent); node = tree->root; } } else { brother = parent->lchild; /* Case 5: 兄弟结点为红色: 以parent为支点, 右旋处理 */ if (rbt_is_red(brother)) { rbt_set_red(parent); rbt_set_black(brother); rbt_right_rotate(tree, parent); /* 参照结点node不变 */ brother = parent->lchild; /* 注意: 此时处理还没有结束,还需要做后续的调整处理 */ } /* Case 6: 兄弟结点为黑色(默认), 且兄弟结点的2个子结点都为黑色 */ if (rbt_is_black(brother->lchild) && rbt_is_black(brother->rchild)) { rbt_set_red(brother); node = parent; } else { /* Case 7: 兄弟结点为黑色(默认), 兄弟节点的右子结点为红色, 左子结点为黑色: 以brother为支点, 左旋处理 */ if (rbt_is_black(brother->lchild)) { rbt_set_red(brother); rbt_set_black(brother->rchild); rbt_left_rotate(tree, brother); /* 参照结点node不变 */ brother = parent->lchild; } /* Case 8: 兄弟结点为黑色(默认), 兄弟结点左孩子结点为红色: 以parent为支点, 右旋处理 */ rbt_copy_color(brother, parent); rbt_set_black(brother->lchild); rbt_set_black(parent); rbt_right_rotate(tree, parent); node = tree->root; } } } rbt_set_black(node); rbt_assert(tree, node); rbt_assert(tree, brother); rbt_assert(tree, parent); return RBT_OK; }
/****************************************************************************** **函数名称: _rbt_delete **功 能: 删除结点(内部接口) **输入参数: ** tree: 红黑树 ** dnode: 将被删除的结点 **输出参数: NONE **返 回: RBT_OK:成功 RBT_ERR:失败 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.12.28 # ******************************************************************************/ static int _rbt_delete(rbt_tree_t *tree, rbt_node_t *dnode) { rbt_node_t *parent, *next, *refer; /* Case 1: 被删结点D的左孩子为叶子结点, 右孩子无限制(可为叶子结点,也可为非叶子结点) */ if (tree->sentinel == dnode->lchild) { parent = dnode->parent; refer = dnode->rchild; refer->parent = parent; if (tree->sentinel == parent) { tree->root = refer; } else if (dnode == parent->lchild) { parent->lchild = refer; } else { /* dnode == parent->rchild */ parent->rchild = refer; } if (rbt_is_red(dnode)) { tree->dealloc(tree->pool, dnode); return RBT_OK; } tree->dealloc(tree->pool, dnode); return rbt_delete_fixup(tree, refer); } /* Case 2: 被删结点D的右孩子为叶子结点, 左孩子不为叶子结点 */ else if (tree->sentinel == dnode->rchild) { parent = dnode->parent; refer = dnode->lchild; refer->parent = parent; if (tree->sentinel == parent) { tree->root = refer; } else if (dnode == parent->lchild) { parent->lchild = refer; } else /* dnode == parent->rchild */ { parent->rchild = refer; } if (rbt_is_red(dnode)) { tree->dealloc(tree->pool, dnode); return RBT_OK; } tree->dealloc(tree->pool, dnode); return rbt_delete_fixup(tree, refer); } /* Case 3: 被删结点D的左右孩子均不为叶子节点 */ /* 3.1 查找dnode的后继结点next */ next = dnode->rchild; while (tree->sentinel != next->lchild) { next = next->lchild; } parent = next->parent; refer = next->rchild; refer->parent = parent; if (next == parent->lchild) { parent->lchild = refer; } else { /* next == parent->rchild */ parent->rchild = refer; } dnode->idx = next->idx; dnode->data = next->data; /* Copy next's satellite data into dnode */ if (rbt_is_red(next)) { /* Not black */ tree->dealloc(tree->pool, next); return RBT_OK; } tree->dealloc(tree->pool, next); return rbt_delete_fixup(tree, refer); }
/****************************************************************************** **函数名称: rbt_insert_fixup **功 能: 插入操作修复(内部接口) **输入参数: ** tree: 红黑树 ** node: 新增节点的地址 **输出参数: NONE **返 回: RBT_OK:成功 RBT_ERR:失败 **实现描述: ** 1. 检查红黑树性质是否被破坏 ** 2. 如果被破坏,则进行对应的处理 **注意事项: 插入节点操作只可能破坏性质④ **作 者: # Qifeng.zou # 2013.12.23 # ******************************************************************************/ static int rbt_insert_fixup(rbt_tree_t *tree, rbt_node_t *node) { rbt_node_t *parent = NULL, *uncle = NULL, *grandpa = NULL, *gparent = NULL; while (rbt_is_red(node)) { parent = node->parent; if (rbt_is_black(parent)) { return RBT_OK; } grandpa = parent->parent; if (parent == grandpa->lchild) { /* 父节点为左节点 */ uncle = grandpa->rchild; /* case 1: 父节点和叔节点为红色 */ if (rbt_is_red(uncle)) { rbt_set_black(parent); rbt_set_black(uncle); if (grandpa != tree->root) { rbt_set_red(grandpa); } node = grandpa; continue; } /* case 2: 叔结点为黑色,结点为左孩子 */ else if (node == parent->lchild) { /* 右旋转: 以grandpa为支点 */ gparent = grandpa->parent; rbt_set_red(grandpa); rbt_set_black(parent); rbt_right_rotate(tree, grandpa); node = gparent; continue; } /* case 3: 叔结点为黑色,结点为右孩子 */ else { /* 左旋转: 以parent为支点 */ rbt_left_rotate(tree, parent); node = parent; continue; } } else /* 父节点为右孩子 */ { uncle = grandpa->lchild; /* case 1: 父节点和叔节点为红色 */ if (rbt_is_red(uncle)) { rbt_set_black(parent); rbt_set_black(uncle); if (grandpa != tree->root) { rbt_set_red(grandpa); } node = grandpa; continue; } /* case 2: 叔结点为黑色,结点为左孩子 */ else if (node == parent->lchild) { /* 右旋转: 以parent为支点 */ rbt_right_rotate(tree, parent); node = parent; continue; } /* case 3: 叔结点为黑色,结点为右孩子 */ else { /* 左旋转: 以grandpa为支点 */ gparent = grandpa->parent; rbt_set_black(parent); rbt_set_red(grandpa); rbt_left_rotate(tree, grandpa); node = gparent; continue; } } } return RBT_OK; }
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); }