Beispiel #1
0
/******************************************************************************
 **函数名称: rbt_right_rotate
 **功    能: 右旋处理
 **输入参数: 
 **     tree: 红黑树
 **     node: 旋转支点
 **输出参数: NONE
 **返    回: RBT_OK:成功 RBT_ERR:失败
 **实现描述: 
 **        G                       G
 **        |                       |
 **        N            ->         L
 **      /   \                   /   \
 **     L     R                 LL    N
 **    / \   / \                     / \
 **   LL LR RL RR                   LR  R
 **                                    / \
 **                                   RL RR
 **            说明: 节点N为旋转支点
 **注意事项: 
 **作    者: # Qifeng.zou # 2014.01.15 #
 ******************************************************************************/
static void rbt_right_rotate(rbt_tree_t *tree, rbt_node_t *node)
{
    rbt_node_t *parent = node->parent, *lchild = node->lchild;
    
    if (tree->sentinel == parent) {
        tree->root = lchild;
        lchild->parent = tree->sentinel;
    }
    else if (node == parent->lchild) {
        rbt_set_lchild(tree, parent, lchild);
    }
    else {
        rbt_set_rchild(tree, parent, lchild);
    }
    rbt_set_lchild(tree, node, lchild->rchild);
    rbt_set_rchild(tree, lchild, node);

    rbt_assert(tree, node);
    rbt_assert(tree, lchild);
    rbt_assert(tree, parent);
}
Beispiel #2
0
int main(){
    Rbt_tree_link a = rbt_create();
    Rbtlink it;
    srand(time(NULL));

    puts("Inserting...");
    for(i=0;i<N;i++) {
	num[i] = rand() % N;
	rbt_insert(a,num[i]);
    }
    
    printf("rbt_size: %d\n",rbt_size(a));

    printf("min value:%d   max value:%d\n",rbt_item(rbt_minimum(a)),rbt_item(rbt_maximum(a)));
    puts("Doing assert...");
    rbt_assert(a);
    puts("Traversing (inorder)...");
    rbt_inorder(a,func);

    for(i=0; i < N; i++)
	rbt_search(a, i);

    puts("Traversing (from max to min)...");
    it = rbt_maximum(a);
    for(i = rbt_size(a)-1; i >= 0; i--) {
	assert(n[i] == rbt_item(it));
	it = rbt_predecessor(it);
    }

    printf("rbt_size: %d\n",rbt_size(a));

    puts("Deleting all values...");
    int i = 0;
    for (i = 0; i < N; ++i) {
	printf("%d deleted\r", num[i]);
	rbt_delete(a, num[i]);
    }

    puts("\nDestroying rbt..");
    rbt_destroy(a);
    puts("OK!");
    return 0;
}
Beispiel #3
0
/******************************************************************************
 **函数名称: rbt_print
 **功    能: 打印红黑树(外部接口)
 **输入参数: 
 **     tree: 红黑树
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.12.17 #
 ******************************************************************************/
int rbt_print(rbt_tree_t *tree)
{
    int depth = 0;
    Stack_t _stack, *stack = &_stack;
    rbt_node_t *node = tree->root, *parent = NULL;

    if (tree->sentinel == node) return 0;

    stack_init(stack, RBT_MAX_DEPTH);

    while (tree->sentinel != node) {
        /* 压左孩子入栈 */
        while (tree->sentinel != node->lchild) {
            rbt_assert(tree, node);
            depth = stack_depth(stack);
            stack_push(stack, node);
            rbt_print_head(tree, node, depth);   /* 打印头:入栈时打印头 出栈时打印尾 */
            node = node->lchild;
        }

        /* 打印最左端的子孙结点 */
        depth = stack_depth(stack);
        rbt_print_head(tree, node, depth);

        /* 最左端的孩子有右孩子 */
        if (tree->sentinel != node->rchild) {
            stack_push(stack, node);
            node = node->rchild;
            continue;
        }
        
        /* 最左端的孩子无右孩子 */
        rbt_print_tail(tree, node, depth);

        parent = stack_gettop(stack);
        if (NULL == parent) {
            return stack_destroy(stack);
        }

        /* 判断最左结点的父结点未处理完成 */
        if (parent->lchild == node) {
            if (tree->sentinel != parent->rchild) {
                node = parent->rchild;
                continue;
            }
        }

        /* 判断最左结点的父结点已处理完成 */
        while ((node == parent->rchild)
            || (tree->sentinel == parent->rchild))
        {
            stack_pop(stack);
            
            depth = stack_depth(stack);
            rbt_print_tail(tree, parent, depth);    /* 打印尾:出栈时打印尾 入栈时已打印头 */

            node = parent;
            parent = stack_gettop(stack);
            if (NULL == parent) {
                return stack_destroy(stack);
            }
        }

        node = parent->rchild;
    }

    return stack_destroy(stack);
}
Beispiel #4
0
/******************************************************************************
 **函数名称: 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;
}
Beispiel #5
0
/******************************************************************************
 **函数名称: rbt_trav
 **功    能: 遍历红黑树(外部接口)
 **输入参数: 
 **     tree: 红黑树
 **     cb: 回调函数
 **     args: 附加参数
 **输出参数: NONE
 **返    回: VOID
 **实现描述: 处理思路可以参考rbt_print(), 但是稍微有些不同之处.
 **注意事项: 
 **作    者: # Qifeng.zou # 2014.12.26 #
 ******************************************************************************/
int rbt_trav(rbt_tree_t *tree, trav_cb_t proc, void *args)
{
    Stack_t _stack, *stack = &_stack;
    rbt_node_t *node = tree->root, *parent;

    if (tree->sentinel == node) { return 0; }

    stack_init(stack, RBT_MAX_DEPTH);

    while (tree->sentinel != node) {
        /* 压左孩子入栈, 直到最左端 */
        while (tree->sentinel != node->lchild) {
            rbt_assert(tree, node);
            stack_push(stack, node);
            node = node->lchild;
        }

        proc(node->data, args); /* 处理最左端结点 */

        /* 最左端结点有右孩子 */
        if (tree->sentinel != node->rchild) {
            stack_push(stack, node); /* 最左端结点入栈 */
            node = node->rchild;
            continue;
        }
        
        /* 最左端结点无右孩子 */
        parent = stack_gettop(stack);
        if (NULL == parent) {
            return stack_destroy(stack);
        }

        if (parent->lchild == node) {
            proc(parent->data, args);   /* 处理最左结点的父结点 */
            if (tree->sentinel != parent->rchild) { /* 有右子树 */
                node = parent->rchild;  /* 处理右子树 */
                continue;
            }
            else {
                stack_pop(stack);
                node = parent;
                parent = stack_gettop(stack);
                if (NULL == parent) {
                    return stack_destroy(stack);
                }
            }
        }

        /* 判断最左结点的父结点已处理完成 */
        while ((node == parent->rchild)
            || (tree->sentinel == parent->rchild))
        {
            stack_pop(stack);
            
            node = parent;
            parent = stack_gettop(stack);
            if (NULL == parent) {
                return stack_destroy(stack);
            }
        }

        proc(parent->data, args); /* 处理有左子树而无右子树的结点 */

        node = parent->rchild;
    }

    return stack_destroy(stack);
}