コード例 #1
0
ファイル: avl.c プロジェクト: dannoy/tools
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;
}
コード例 #2
0
ファイル: avl.c プロジェクト: mmikulicic/acaros
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;
}
コード例 #3
0
ファイル: avl_tree.c プロジェクト: object8421/tanlz
/******************************************************************************
 **函数名称: 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);
}
コード例 #4
0
ファイル: avl.c プロジェクト: dannoy/tools
int avl_delete(struct avl *t, int key)
{
    if(t && t->root) t->root = _avl_delete(t->root, key);

    return 0;
}
コード例 #5
0
ファイル: avl_tree.c プロジェクト: object8421/tanlz
/******************************************************************************
 **函数名称: _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;
}