Exemple #1
0
/**
 * Travel subtree for find the value in preorder.
 */
_avlnode_t* _avl_tree_find_value(const _avl_tree_t* cpt_avl_tree, const _avlnode_t* cpt_root, const void* cpv_value) 
{
    bool_t b_result = false;

    assert(cpt_avl_tree != NULL);
    assert(cpv_value != NULL);
    assert(_avl_tree_is_inited(cpt_avl_tree));

    if (cpt_root == NULL) {
        return NULL;
    }

    b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
    _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpv_value, cpt_root->_pby_data, &b_result);
    if (b_result) {
        return _avl_tree_find_value(cpt_avl_tree, cpt_root->_pt_left, cpv_value);
    }

    b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
    _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpt_root->_pby_data, cpv_value, &b_result);
    if (b_result) {
        return _avl_tree_find_value(cpt_avl_tree, cpt_root->_pt_right, cpv_value);
    } else {
        return (_avlnode_t*)cpt_root;
    }
}
Exemple #2
0
/**
 * Return an iterator to the first element that is equal to or greater than a specific element.
 */
_avl_tree_iterator_t _avl_tree_lower_bound(const _avl_tree_t* cpt_avl_tree, const void* cpv_value)
{
    _avlnode_t*          pt_cur = NULL;
    _avlnode_t*          pt_prev = NULL;
    bool_t               b_less = false;
    bool_t               b_greater = false;
    _avl_tree_iterator_t it_iter;

    assert(cpt_avl_tree != NULL);
    assert(cpv_value != NULL);
    assert(_avl_tree_is_inited(cpt_avl_tree));

    it_iter = _create_avl_tree_iterator();
    _AVL_TREE_ITERATOR_TREE_POINTER(it_iter) = (void*)cpt_avl_tree;

    if (!_avl_tree_empty(cpt_avl_tree)) {
        pt_prev = cpt_avl_tree->_t_avlroot._pt_parent;

        b_less = b_greater = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
        _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpv_value, pt_prev->_pby_data, &b_less);
        _avl_tree_elem_compare_auxiliary(cpt_avl_tree, pt_prev->_pby_data, cpv_value, &b_greater);

        pt_cur = (b_less || !b_greater) ? pt_prev->_pt_left : pt_prev->_pt_right;
        while (pt_cur != NULL) {
            pt_prev = pt_cur;
            b_less = b_greater = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
            _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpv_value, pt_prev->_pby_data, &b_less);
            _avl_tree_elem_compare_auxiliary(cpt_avl_tree, pt_prev->_pby_data, cpv_value, &b_greater);

            pt_cur = (b_less || !b_greater) ? pt_prev->_pt_left : pt_prev->_pt_right;
        }

        if (b_less || !b_greater) {
            assert(pt_prev->_pt_left == NULL);
            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
            assert(_avl_tree_iterator_belong_to_avl_tree(cpt_avl_tree, it_iter));
        } else {
            assert(pt_prev->_pt_right == NULL);
            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
            it_iter = _avl_tree_iterator_next(it_iter);
        }
    } else {
        it_iter = _avl_tree_end(cpt_avl_tree);
    }

    return it_iter;
}
/**
 * Insert the value into subtree.
 */
_avl_tree_insert_result_t _avl_tree_insert_avlnode(
    const _avl_tree_t* cpt_avl_tree, _avlnode_t* pt_root, const void* cpv_value)
{
    _avl_tree_insert_result_t t_insert_result;
    bool_t           b_result = false;

    assert(cpt_avl_tree != NULL);
    assert(cpv_value != NULL);
    assert(_avl_tree_is_inited(cpt_avl_tree));

    /* if root is NULL then allocate memory */
    if(pt_root == NULL)
    {
        pt_root = _alloc_allocate(
            (_alloc_t*)&cpt_avl_tree->_t_allocator, _AVL_TREE_NODE_SIZE(_GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree)), 1);
        assert(pt_root != NULL);
        _avl_tree_init_elem_auxiliary((_avl_tree_t*)cpt_avl_tree, pt_root);

        pt_root->_pt_left = pt_root->_pt_right = NULL;
        pt_root->_un_height = 0;
        t_insert_result._pt_adjust = pt_root;
        t_insert_result._pt_new = pt_root;
        b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
        _GET_AVL_TREE_TYPE_COPY_FUNCTION(cpt_avl_tree)(pt_root->_pby_data, cpv_value, &b_result);
        assert(b_result);

        return t_insert_result;
    }

    /* compare the value and current node */
    /* if value < current node then insert into left subtree */
    b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_avl_tree);
    _avl_tree_elem_compare_auxiliary(cpt_avl_tree, cpv_value, pt_root->_pby_data, &b_result);
    if(b_result)
    {
        t_insert_result = _avl_tree_insert_avlnode(cpt_avl_tree, pt_root->_pt_left, cpv_value);
        pt_root->_pt_left = t_insert_result._pt_adjust;
        pt_root->_pt_left->_pt_parent = pt_root;

        pt_root = _avl_tree_rebalance(pt_root);
        t_insert_result._pt_adjust = pt_root;

        return t_insert_result;
    }
    /* else insert into right subtree */
    else
    {
        t_insert_result = _avl_tree_insert_avlnode(cpt_avl_tree, pt_root->_pt_right, cpv_value);
        pt_root->_pt_right =  t_insert_result._pt_adjust;
        pt_root->_pt_right->_pt_parent = pt_root;

        pt_root = _avl_tree_rebalance(pt_root);
        t_insert_result._pt_adjust = pt_root;

        return t_insert_result;
    }
}