/* * 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; }
/****************************************************************************** **函数名称: 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; }
/* * 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); }
/****************************************************************************** **函数名称: 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; }
/****************************************************************************** **函数名称: 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; }
/* 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; }
/****************************************************************************** **函数名称: 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; }
/****************************************************************************** **函数名称: _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; }
/****************************************************************************** **函数名称: 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; }