Esempio n. 1
0
/*
 * Template for performing a double rotation ---
 *
 * sign > 0:  Rotate counterclockwise (left) rooted at B, then
 *		     clockwise (right) rooted at A:
 *
 *           P?            P?          P?
 *           |             |           |
 *           A             A           E
 *          / \           / \        /   \
 *         B   C?  =>    E   C? =>  B     A
 *        / \           / \        / \   / \
 *       D?  E         B   G?     D?  F?G?  C?
 *          / \       / \
 *         F?  G?    D?  F?
 *
 * (nodes marked with ? may not exist)
 *
 * sign < 0:  Rotate clockwise (right) rooted at B, then
 *		     counterclockwise (left) rooted at A:
 *
 *         P?          P?              P?
 *         |           |               |
 *         A           A               E
 *        / \         / \            /   \
 *       C?  B   =>  C?  E    =>    A     B
 *          / \         / \        / \   / \
 *         E   D?      G?  B      C?  G?F?  D?
 *        / \             / \
 *       G?  F?          F?  D?
 *
 * Returns a pointer to E and updates balance factors.  Except for those
 * two things, this function is equivalent to:
 *	avl_rotate(root_ptr, B, -sign);
 *	avl_rotate(root_ptr, A, +sign);
 *
 * See comment in avl_handle_subtree_growth() for explanation of balance
 * factor updates.
 */
static AVL_INLINE struct avl_tree_node *
avl_do_double_rotate(struct avl_tree_node ** const root_ptr,
		     struct avl_tree_node * const B,
		     struct avl_tree_node * const A, const int sign)
{
	struct avl_tree_node * const E = avl_get_child(B, +sign);
	struct avl_tree_node * const F = avl_get_child(E, -sign);
	struct avl_tree_node * const G = avl_get_child(E, +sign);
	struct avl_tree_node * const P = avl_get_parent(A);
	const int e = avl_get_balance_factor(E);

	avl_set_child(A, -sign, G);
	avl_set_parent_balance(A, E, ((sign * e >= 0) ? 0 : -e));

	avl_set_child(B, +sign, F);
	avl_set_parent_balance(B, E, ((sign * e <= 0) ? 0 : -e));

	avl_set_child(E, +sign, A);
	avl_set_child(E, -sign, B);
	avl_set_parent_balance(E, P, 0);

	if (G)
		avl_set_parent(G, A);

	if (F)
		avl_set_parent(F, B);

	avl_replace_child(root_ptr, P, A, E);

	return E;
}
Esempio n. 2
0
/******************************************************************************
 **函数名称: avl_ll_balance
 **功    能: LL型平衡化处理 - 向右旋转(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 左边失去平衡的结点
 **输出参数: NONE
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 ** 场景1: LL型
 **              A                  B
 **             / \                / \
 **            B   C      ->      BL  A
 **           / \                /   / \
 **          BL BR              X   BR  C
 **         /
 **        X
 **             (1)                (2)
 ** 说明: 结点A是失衡结点,此时当结点B的平衡因子为1时,可判断为LL型。
 **注意事项:
 **     1. 图(1)中A表示左边失衡的结点 图(2)表示平衡处理的结果
 **作    者: # Qifeng.zou # 2013.12.13 #
 ******************************************************************************/
int avl_ll_balance(avl_tree_t *tree, avl_node_t *node)
{
    avl_node_t *lchild = node->lchild, *parent = node->parent;

    avl_set_lchild(node, lchild->rchild);
    node->bf = AVL_EH;

    avl_set_rchild(lchild, node);
    lchild->bf = AVL_EH;

    avl_replace_child(tree, parent, node, lchild);

    return AVL_OK;
}
Esempio n. 3
0
/*
 * Template for performing a single rotation ---
 *
 * sign > 0:  Rotate clockwise (right) rooted at A:
 *
 *           P?            P?
 *           |             |
 *           A             B
 *          / \           / \
 *         B   C?  =>    D?  A
 *        / \               / \
 *       D?  E?            E?  C?
 *
 * (nodes marked with ? may not exist)
 *
 * sign < 0:  Rotate counterclockwise (left) rooted at A:
 *
 *           P?            P?
 *           |             |
 *           A             B
 *          / \           / \
 *         C?  B   =>    A   D?
 *            / \       / \
 *           E?  D?    C?  E?
 *
 * This updates pointers but not balance factors!
 */
static AVL_INLINE void
avl_rotate(struct avl_tree_node ** const root_ptr,
	   struct avl_tree_node * const A, const int sign)
{
	struct avl_tree_node * const B = avl_get_child(A, -sign);
	struct avl_tree_node * const E = avl_get_child(B, +sign);
	struct avl_tree_node * const P = avl_get_parent(A);

	avl_set_child(A, -sign, E);
	avl_set_parent(A, B);

	avl_set_child(B, +sign, A);
	avl_set_parent(B, P);

	if (E)
		avl_set_parent(E, A);

	avl_replace_child(root_ptr, P, A, B);
}
Esempio n. 4
0
/******************************************************************************
 **函数名称: avl_lr_balance
 **功    能: LR型平衡化处理 - 先左旋转 再向右旋转(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 左边失去平衡的结点
 **输出参数: NONE
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 ** 场景1: LL型
 **              A                  B
 **             / \                / \
 **            B   C      ->      BL  A
 **           / \                /   / \
 **          BL BR              X   BR  C
 **         /
 **        X
 **             (1)                (2)
 ** 说明: 结点A是失衡结点,此时当结点B的平衡因子为1时,可判断为LL型。
 ** 场景2: LR型
 **              A                    C
 **             / \                /     \
 **            B  AR      ->      B       A
 **           / \                / \     / \
 **          BL  C              BL CL   CR AR
 **             / \
 **            CL CR
 **             (1)                (2)
 ** 说明: 结点A是失衡结点,此时当结点B的平衡因子为-1时,可判断为LR型。
 **       虽然此时结点C的平衡因子的值可能为:-1, 0, 1.
 **       但旋转处理的方式是一致的,只是旋转之后的平衡因子不一致.
 **注意事项:
 **     1. 图(1)中A表示左边失衡的结点 图(2)表示平衡处理的结果
 **作    者: # Qifeng.zou # 2013.12.13 #
 ******************************************************************************/
int avl_lr_balance(avl_tree_t *tree, avl_node_t *node)
{
    avl_node_t *lchild = node->lchild,
               *parent = node->parent, *lrchild = NULL;


    lrchild = lchild->rchild;
    switch(lrchild->bf) {
        case AVL_LH:
        {
            node->bf = AVL_RH;
            lchild->bf = AVL_EH;
            lrchild->bf = AVL_EH;
            break;
        }
        case AVL_EH:
        {
            node->bf = AVL_EH;
            lchild->bf = AVL_EH;
            lrchild->bf = AVL_EH;
            break;
        }
        case AVL_RH:
        {
            node->bf = AVL_EH;
            lchild->bf = AVL_LH;
            lrchild->bf = AVL_EH;
            break;
        }
    }

    avl_set_rchild(lchild, lrchild->lchild);
    avl_set_lchild(lrchild, lchild);
    avl_set_lchild(node, lrchild->rchild);
    avl_set_rchild(lrchild, node);

    avl_replace_child(tree, parent, node, lrchild);

    return AVL_OK;
}
Esempio n. 5
0
/******************************************************************************
 **函数名称: avl_rl_balance
 **功    能: RL型平衡化处理 - 先向右旋转 再向左旋转(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 右边失去平衡的结点
 **输出参数: NONE
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 ** 场景1: RL型
 **              A                    B
 **             / \                /    \
 **            AL  C      ->      A      C
 **               / \            / \    / \
 **              B  CR          AL BL  BR CR
 **             / \
 **            BL BR
 **              (1)                (2)
 ** 说明: 结点A是失衡结点,此时当结点C的平衡因子为1时,可判断为RL型。
 **       虽然此时结点B的平衡因子的值可能为:-1, 0, 1.
 **       但旋转处理的方式是一致的,只是旋转之后的平衡因子不一致.
 **注意事项:
 **     1. 图(1)中A表示右边失衡的结点 图(2)表示平衡处理的结果
 **作    者: # Qifeng.zou # 2013.12.13 #
 ******************************************************************************/
int avl_rl_balance(avl_tree_t *tree, avl_node_t *node)
{
    avl_node_t *rchild = node->rchild,
        *parent = node->parent, *rlchild = NULL;

    rlchild = rchild->lchild;
    switch(rlchild->bf) {
        case AVL_LH:
        {
            node->bf = AVL_EH;
            rchild->bf = AVL_RH;
            rlchild->bf = AVL_EH;
            break;
        }
        case AVL_EH:
        {
            node->bf = AVL_EH;
            rchild->bf = AVL_EH;
            rlchild->bf = AVL_EH;
            break;
        }
        case AVL_RH:
        {
            node->bf = AVL_LH;
            rchild->bf = AVL_EH;
            rlchild->bf = AVL_EH;
            break;
        }
    }

    avl_set_lchild(rchild, rlchild->rchild);
    avl_set_rchild(rlchild, rchild);
    avl_set_rchild(node, rlchild->lchild);
    avl_set_lchild(rlchild, node);

    avl_replace_child(tree, parent, node, rlchild);

    return AVL_OK;
}
Esempio n. 6
0
/* Swaps node X, which must have 2 children, with its in-order successor, then
 * unlinks node X.  Returns the parent of X just before unlinking, without its
 * balance factor having been updated to account for the unlink.  */
static AVL_INLINE struct avl_tree_node *
avl_tree_swap_with_successor(struct avl_tree_node **root_ptr,
			     struct avl_tree_node *X,
			     bool *left_deleted_ret)
{
	struct avl_tree_node *Y, *ret;

	Y = X->right;
	if (!Y->left) {
		/*
		 *     P?           P?           P?
		 *     |            |            |
		 *     X            Y            Y
		 *    / \          / \          / \
		 *   A   Y    =>  A   X    =>  A   B?
		 *      / \          / \
		 *    (0)  B?      (0)  B?
		 *
		 * [ X unlinked, Y returned ]
		 */
		ret = Y;
		*left_deleted_ret = false;
	} else {
		struct avl_tree_node *Q;

		do {
			Q = Y;
			Y = Y->left;
		} while (Y->left);

		/*
		 *     P?           P?           P?
		 *     |            |            |
		 *     X            Y            Y
		 *    / \          / \          / \
		 *   A   ...  =>  A  ...   =>  A  ...
		 *       |            |            |
		 *       Q            Q            Q
		 *      /            /            /
		 *     Y            X            B?
		 *    / \          / \
		 *  (0)  B?      (0)  B?
		 *
		 *
		 * [ X unlinked, Q returned ]
		 */

		Q->left = Y->right;
		if (Q->left)
			avl_set_parent(Q->left, Q);
		Y->right = X->right;
		avl_set_parent(X->right, Y);
		ret = Q;
		*left_deleted_ret = true;
	}

	Y->left = X->left;
	avl_set_parent(X->left, Y);

	Y->parent_balance = X->parent_balance;
	avl_replace_child(root_ptr, avl_get_parent(X), X, Y);

	return ret;
}
Esempio n. 7
0
/******************************************************************************
 **函数名称: avl_delete_left_balance
 **功    能: 结点node的左子树某结点被删除, 左高度降低后, 平衡化处理(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 结点node的左子树的某个结点已被删除
 **输出参数:
 **     lower: 高度是否变化
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 **注意事项:
 **作    者: # Qifeng.zou # 2013.12.19 #
 ******************************************************************************/
int avl_delete_left_balance(avl_tree_t *tree, avl_node_t *node, bool *lower)
{
    avl_node_t *rchild = NULL, *rlchild = NULL, *parent = node->parent;

    switch(node->bf) {
        case AVL_LH:    /* 左高: 左子树高度减1 树变矮 */
        {
            node->bf = AVL_EH;
            *lower = true;
            break;
        }
        case AVL_EH:    /* 等高: 左子树高度减1 树高度不变 */
        {
            node->bf = AVL_RH;
            *lower = false;
            break;
        }
        case AVL_RH:    /* 右高: 左子树高度减1 树失去平衡 */
        {
            rchild = node->rchild;
            switch(rchild->bf) {
                case AVL_EH:    /* RR型: 向左旋转 */
                case AVL_RH:    /* RR型: 向左旋转 */
                {
                    if (AVL_EH == rchild->bf) {
                        *lower = false;
                        rchild->bf = AVL_LH;
                        node->bf = AVL_RH;
                    }
                    else if (AVL_RH == rchild->bf) {
                        *lower = true;
                        rchild->bf = AVL_EH;
                        node->bf = AVL_EH;
                    }

                    avl_set_rchild(node, rchild->lchild);
                    avl_set_lchild(rchild, node);
                    avl_replace_child(tree, parent, node, rchild);

                    avl_assert(node);
                    avl_assert(rchild);
                    break;
                }
                case AVL_LH:    /* RL型: 先向右旋转 再向左旋转 */
                {
                    *lower = true;
                    rlchild = rchild->lchild;
                    switch(rlchild->bf) {
                        case AVL_LH:
                        {
                            node->bf = AVL_EH;
                            rchild->bf = AVL_RH;
                            rlchild->bf = AVL_EH;
                            break;
                        }
                        case AVL_EH:
                        {
                            node->bf = AVL_EH;
                            rchild->bf = AVL_EH;
                            rlchild->bf = AVL_EH;
                            break;
                        }
                        case AVL_RH:
                        {
                            node->bf = AVL_LH;
                            rchild->bf = AVL_EH;
                            rlchild->bf = AVL_EH;
                            break;
                        }
                    }

                    avl_set_rchild(node, rlchild->lchild);
                    avl_set_lchild(rchild, rlchild->rchild);
                    avl_set_lchild(rlchild, node);
                    avl_set_rchild(rlchild, rchild);

                    avl_replace_child(tree, parent, node, rlchild);

                    avl_assert(parent);
                    avl_assert(node);
                    avl_assert(rchild);
                    avl_assert(rlchild);
                    break;
                }
            }
            break;
        }
    }

    return AVL_OK;
}
Esempio n. 8
0
/******************************************************************************
 **函数名称: _avl_delete
 **功    能: 搜索并删除指定的key值结点(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 以node为根结点的子树
 **     idx: 被删除的关键字
 **     key: 主键(Primary idx)
 **输出参数:
 **     lower: 高度是否降低
 **     data: 附加数据
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 **注意事项:
 **作    者: # Qifeng.zou # 2013.12.19 #
 ******************************************************************************/
static int _avl_delete(avl_tree_t *tree, avl_node_t *node,
        int64_t idx, const avl_key_t *key, bool *lower, void **data)
{
    int ret;
    avl_node_t *parent = node->parent;

    /* 1. 查找需要被删除的结点 */
    if (idx < node->idx) { /* 左子树上查找 */
    AVL_LESS:
        if (NULL == node->lchild) {
            *data = NULL;
            return AVL_OK;
        }

        _avl_delete(tree, node->lchild, idx, key, lower, data);
        avl_assert(node);
        avl_assert(node->lchild);
        if (true == *lower) {
            return avl_delete_left_balance(tree, node, lower);
        }
        return AVL_OK;
    }
    else if (idx > node->idx) { /* 右子树上查找 */
    AVL_GREATER:
        if (NULL == node->rchild) {
            *data = NULL;
            return AVL_OK;
        }

        _avl_delete(tree, node->rchild, idx, key, lower, data);
        avl_assert(node);
        avl_assert(node->rchild);
        if (true == *lower) {
            return avl_delete_right_balance(tree, node, lower);
        }
        return AVL_OK;
    }
    else {
        ret = tree->cmp_cb(key->v, node->data);
        if (0 == ret) {
            goto AVL_EQUAL;
        }
        else if (ret < 0) {
            goto AVL_LESS;
        }
        else if (ret > 0) {
            goto AVL_GREATER;
        }
    }

AVL_EQUAL:

    /* 2. 已找到将被删除的结点node */
    *data = node->data;

    /* 2.1 右子树为空, 只需接它的左子树(叶子结点也走这) */
    if (NULL == node->rchild) {
        *lower = true;

        avl_replace_child(tree, parent, node, node->lchild);

        avl_assert(parent);
        avl_assert(node->lchild);
        tree->dealloc(tree->pool, node), node = NULL;
        return AVL_OK;
    }
    /* 2.2 左子树空, 只需接它的右子树 */
    else if (NULL == node->lchild) {
        *lower = true;

        avl_replace_child(tree, parent, node, node->rchild)

        avl_assert(parent);
        avl_assert(node->rchild);
        tree->dealloc(tree->pool, node), node = NULL;
        return AVL_OK;
    }

    /* 2.3 左右子树均不为空: 查找左子树最右边的结点 替换被删的结点 */
    avl_replace_and_delete(tree, node, node->lchild, lower);
    if (true == *lower) {
        avl_assert(node);
        return avl_delete_left_balance(tree, node, lower);
    }

    return AVL_OK;
}
Esempio n. 9
0
/******************************************************************************
 **函数名称: avl_delete_right_balance
 **功    能: 结点node的右子树某结点被删除, 左高度降低后, 平衡化处理(内部接口)
 **输入参数:
 **     tree: 平衡二叉树
 **     node: 结点node的右子树的某个结点已被删除
 **输出参数:
 **     lower: 高度是否变化
 **返    回: AVL_OK:成功 AVL_ERR:失败
 **实现描述:
 **注意事项:
 **作    者: # Qifeng.zou # 2013.12.19 #
 ******************************************************************************/
int avl_delete_right_balance(avl_tree_t *tree, avl_node_t *node, bool *lower)
{
    avl_node_t *lchild = NULL, *lrchild = NULL, *parent = node->parent;

    switch(node->bf) {
        case AVL_LH:    /* 左高: 右子树高度减1 树失去平衡 */
        {
            lchild = node->lchild;
            switch(lchild->bf)
            {
                case AVL_EH:    /* LL型: 向右旋转 */
                case AVL_LH:    /* LL型: 向右旋转 */
                {
                    if (AVL_EH == lchild->bf) {
                        *lower = false;
                        lchild->bf = AVL_RH;
                        node->bf = AVL_LH;
                    }
                    else {
                        *lower = true;
                        lchild->bf = AVL_EH;
                        node->bf = AVL_EH;
                    }

                    avl_set_lchild(node, lchild->rchild);
                    avl_set_rchild(lchild, node);
                    avl_replace_child(tree, parent, node, lchild);

                    avl_assert(parent);
                    avl_assert(node);
                    avl_assert(lchild);
                    break;
                }
                case AVL_RH:    /* LR型: 先向左旋转 再向右旋转 */
                {
                    *lower = true;
                    lrchild = lchild->rchild;
                    switch(lrchild->bf) {
                        case AVL_LH:
                        {
                            node->bf = AVL_RH;
                            lchild->bf = AVL_EH;
                            lrchild->bf = AVL_EH;
                            break;
                        }
                        case AVL_EH:
                        {
                            node->bf = AVL_EH;
                            lchild->bf = AVL_EH;
                            lrchild->bf = AVL_EH;
                            break;
                        }
                        case AVL_RH:
                        {
                            node->bf = AVL_EH;
                            lchild->bf = AVL_LH;
                            lrchild->bf = AVL_EH;
                            break;
                        }
                    }

                    avl_set_lchild(node, lrchild->rchild);
                    avl_set_rchild(lchild, lrchild->lchild);
                    avl_set_rchild(lrchild, node);
                    avl_set_lchild(lrchild, lchild);

                    avl_replace_child(tree, parent, node, lrchild);

                    avl_assert(parent);
                    avl_assert(node);
                    avl_assert(lchild);
                    avl_assert(lrchild);
                    break;
                }
            }
            break;
        }
        case AVL_EH:    /* 等高: 右子树高度减1 树高度不变 */
        {
            node->bf = AVL_LH;
            *lower = false;
            break;
        }
        case AVL_RH:    /* 右高: 右子树高度减1 树变矮 */
        {
            node->bf = AVL_EH;
            *lower = true;
            break;
        }
    }
    return AVL_OK;
}