// 删除一个结点
// 考虑的情况
// 空树:该情况不可能出现,因为y已经指向树中的某一结点
// 只有一个根节点的树
// 有多个结点的树
prbtree rbt_delete_node(prbtree T, prbt_node z)
{
     // y指向要删除的结点
     prbt_node y;
     prbt_node x;
     if (z->left == nil || z->right == nil)
     {
	  y = z;
     }
     else
     {
	  y = rbt_successor(z);
     }
     // x 指向要连接的子树
     if (y->left != nil)
     {
	  x = y->left;
     }
     else
     {
	  x = y->right;
     }
     x->parent = y->parent;
     if (y->parent == nil)
     {
	  T = x;
     }
     else if (y->parent->left == y)
     {
	  y->parent->left = x;
     }
     else
     {
	  y->parent->right = x;
     }
// 如果y != z 则y为z的后继结点,将z的key赋值为y的key
     if (y != z)
     {
	  z->key = y->key;
	  // 将z的卫星数据赋值为y的卫星数据
	  // ...
     }
     if (y->color == BLACK)
     {
	  T = rbt_delete_fixup(T, x);
     }
     return T;
}
Ejemplo n.º 2
0
/******************************************************************************
 **函数名称: _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);
}