static struct avl_node *_avl_delete(struct avl_node *n, int key) { if(!n) return NULL; if(key < K(n)) L(n) = _avl_delete(L(n), key); else if(key > K(n)) R(n) = _avl_delete(R(n), key); else { // key == K(n) if(NULL == L(n) || NULL == R(n)) { struct avl_node *tmp = L(n) ? L(n) : R(n); if(tmp) { *n = *tmp; // copy contents of child to n } else { // n is leaf tmp = n; n = NULL; } free(tmp); } else { // two children case struct avl_node *d = _avl_minimum(n); K(n) = K(d); R(n) = _avl_delete(d, key); } } // no child case if(!n) return NULL; H(n) = MAX(HH(n->left), HH(n->right)) + 1; int bf = BF(n); if(bf > 1) { if(0 > BF(L(n))) { // LR case L(n) = _leftRotate(L(n)); } // else LL case return _rightRotate(n); } if(bf < -1) { if(0 < BF(R(n))) { // RL case R(n) = _rightRotate(R(n)); } // else RR case return _leftRotate(n); } return n; }
avl_res_t _avl_delete(avl_node_t* node, avl_node_t** root, avl_compare_t compare) { if(!*root) { // panic("avl_delete: not found"); } // pool_slot_t *el = avl_entry(node, pool_slot_t, range); if(node == *root) { // debug //klogf(LOG_DEBUG, "avl_delete: found node %p start 0x%x\n", node, el->start); if((node->left == 0) && (node->right == 0)) { *root = 0; return AVL_BALANCE; } else if((node->left == 0) || (node->right == 0)) { avl_node_t *child; if(node->right) child = node->right; else child = node->left; *root = child; return AVL_BALANCE; } else { avl_node_t **successor = &node->left; while((*successor)->right) { successor = &(*successor)->right; } avl_node_t *oldsucc = *successor; avl_swap(root, successor); if(_avl_delete(node, &oldsucc->left, compare) == AVL_BALANCE) return avl_grownRight(root); } } else if(compare(node, *root) < 0) { if(_avl_delete(node, &(*root)->left, compare) == AVL_BALANCE) return avl_grownRight(root); } else if(compare(node, *root) > 0) { if(_avl_delete(node, &(*root)->right, compare) == AVL_BALANCE) return avl_grownLeft(root); } else { // panic("duplicate node"); } return AVL_OK; }
/****************************************************************************** **函数名称: avl_delete **功 能: 删除key值结点(对外接口) **输入参数: ** tree: 平衡二叉树 ** key: 被删除的关键字 ** len: 关键字长度 **输出参数: ** data: 附加数据 **返 回: AVL_OK:成功 AVL_ERR:失败 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.12.19 # ******************************************************************************/ int avl_delete(avl_tree_t *tree, void *_key, int len, void **data) { int64_t idx; avl_key_t key; bool lower = false; if (NULL == tree->root) { *data = NULL; return AVL_OK; } idx = tree->key_cb(_key, len); key.v = _key; key.len = len; return _avl_delete(tree, tree->root, idx, &key, &lower, data); }
int avl_delete(struct avl *t, int key) { if(t && t->root) t->root = _avl_delete(t->root, key); return 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; }