Пример #1
0
/**
 * Travel subtree for find the value in preorder.
 */
_rbnode_t* _rb_tree_find_value(const _rb_tree_t* cpt_rb_tree, const _rbnode_t* cpt_root, const void* cpv_value)
{
    bool_t b_result = false;

    assert(cpt_rb_tree != NULL);
    assert(cpv_value != NULL);
    assert(_rb_tree_is_inited(cpt_rb_tree));

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

    b_result = _GET_RB_TREE_TYPE_SIZE(cpt_rb_tree);
    _rb_tree_elem_compare_auxiliary(cpt_rb_tree, cpv_value, cpt_root->_pby_data, &b_result);
    if(b_result)
    {
        return _rb_tree_find_value(cpt_rb_tree, cpt_root->_pt_left, cpv_value);
    }

    b_result = _GET_RB_TREE_TYPE_SIZE(cpt_rb_tree);
    _rb_tree_elem_compare_auxiliary(cpt_rb_tree, cpt_root->_pby_data, cpv_value, &b_result);
    if(b_result)
    {
        return _rb_tree_find_value(cpt_rb_tree, cpt_root->_pt_right, cpv_value);
    }
    else
    {
        return (_rbnode_t*)cpt_root;
    }
}
Пример #2
0
/**
 * Destroy the subtree with postorder traverse.
 */
_rbnode_t* _rb_tree_destroy_subtree(_rb_tree_t* pt_rb_tree, _rbnode_t* pt_root)
{
    bool_t b_result = false;

    assert(pt_rb_tree != NULL);
    assert(_rb_tree_is_inited(pt_rb_tree) || _rb_tree_is_created(pt_rb_tree));

    if(pt_root != NULL)
    {
        pt_root->_pt_left = _rb_tree_destroy_subtree(pt_rb_tree, pt_root->_pt_left);
        pt_root->_pt_right = _rb_tree_destroy_subtree(pt_rb_tree, pt_root->_pt_right);

        assert(pt_root->_pt_left == NULL && pt_root->_pt_right == NULL);

        b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
        _GET_RB_TREE_TYPE_DESTROY_FUNCTION(pt_rb_tree)(pt_root->_pby_data, &b_result);
        assert(b_result);
        _alloc_deallocate(&pt_rb_tree->_t_allocator, pt_root, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1);
    }

    return NULL;
}
Пример #3
0
/**
 * Get data value referenced by iterator.
 */
void _rb_tree_iterator_get_value(_rb_tree_iterator_t it_iter, void* pv_value)
{
    assert(pv_value != NULL);
    assert(_rb_tree_iterator_belong_to_rb_tree(_RB_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_rb_tree_iterator_equal(it_iter, _rb_tree_end(_RB_TREE_ITERATOR_TREE(it_iter))));

    /* char* */
    if (strncmp(_GET_RB_TREE_TYPE_BASENAME(_RB_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
        *(char**)pv_value = (char*)string_c_str((string_t*)((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data);
    } else {
        bool_t b_result = _GET_RB_TREE_TYPE_SIZE(_RB_TREE_ITERATOR_TREE(it_iter));
        _GET_RB_TREE_TYPE_COPY_FUNCTION(_RB_TREE_ITERATOR_TREE(it_iter))(
            pv_value, ((_rbnode_t*)_RB_TREE_ITERATOR_COREPOS(it_iter))->_pby_data, &b_result);
        assert(b_result);
    }
}
Пример #4
0
/**
 * Initialize element auxiliary function
 */
void _rb_tree_init_elem_auxiliary(_rb_tree_t* pt_rb_tree, _rbnode_t* pt_node)
{
    assert(pt_rb_tree != NULL);
    assert(pt_node != NULL);
    assert(_rb_tree_is_inited(pt_rb_tree) || _rb_tree_is_created(pt_rb_tree));

    /* initialize new elements */
    if(_GET_RB_TREE_TYPE_STYLE(pt_rb_tree) == _TYPE_CSTL_BUILTIN)
    {
        /* get element type name */
        char s_elemtypename[_TYPE_NAME_SIZE + 1];
        _type_get_elem_typename(_GET_RB_TREE_TYPE_NAME(pt_rb_tree), s_elemtypename);

        _GET_RB_TREE_TYPE_INIT_FUNCTION(pt_rb_tree)(pt_node->_pby_data, s_elemtypename);
    }
    else
    {
        bool_t b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
        _GET_RB_TREE_TYPE_INIT_FUNCTION(pt_rb_tree)(pt_node->_pby_data, &b_result);
        assert(b_result);
    }
}
Пример #5
0
/**
 * Insert the value into subtree.
 */
_rbnode_t* _rb_tree_insert_rbnode(_rb_tree_t* pt_rb_tree, const void* cpv_value)
{
    _rbnode_t* pt_parent = NULL;
    _rbnode_t* pt_cur = NULL;
    bool_t     b_result = false;
    bool_t     b_less = false;

    assert(pt_rb_tree != NULL);
    assert(cpv_value != NULL);
    assert(_rb_tree_is_inited(pt_rb_tree));

    /* if the rb tree is empty */
    if(_rb_tree_empty(pt_rb_tree))
    {
        /* allocat a new root */
        pt_cur = _alloc_allocate(
                     (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1);
        assert(pt_cur != NULL);
        _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur);
        /* set its color is BLACK */
        pt_cur->_pt_left = pt_cur->_pt_right = NULL;
        pt_cur->_t_color = BLACK;
        pt_cur->_pt_parent = (_rbnode_t*)&pt_rb_tree->_t_rbroot;
        b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
        _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result);
        assert(b_result);
        /* insert the node */
        pt_rb_tree->_t_rbroot._pt_parent = pt_cur;
    }
    else
    {
        pt_parent = pt_rb_tree->_t_rbroot._pt_parent;

        b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
        _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less);

        if(b_less)
        {
            pt_cur = pt_parent->_pt_left;
        }
        else
        {
            pt_cur = pt_parent->_pt_right;
        }
        /* from the root to insert position */
        while(pt_cur != NULL)
        {
            /* next current position */
            pt_parent = pt_cur;
            b_less = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
            _rb_tree_elem_compare_auxiliary(pt_rb_tree, cpv_value, pt_parent->_pby_data, &b_less);

            if(b_less)
            {
                pt_cur = pt_parent->_pt_left;
            }
            else
            {
                pt_cur = pt_parent->_pt_right;
            }
        }

        /* allocate new node */
        pt_cur = _alloc_allocate(
                     (_alloc_t*)&pt_rb_tree->_t_allocator, _RB_TREE_NODE_SIZE(_GET_RB_TREE_TYPE_SIZE(pt_rb_tree)), 1);
        assert(pt_cur != NULL);
        _rb_tree_init_elem_auxiliary(pt_rb_tree, pt_cur);

        pt_cur->_pt_left = pt_cur->_pt_right = NULL;
        pt_cur->_t_color = RED;
        pt_cur->_pt_parent = pt_parent;
        b_result = _GET_RB_TREE_TYPE_SIZE(pt_rb_tree);
        _GET_RB_TREE_TYPE_COPY_FUNCTION(pt_rb_tree)(pt_cur->_pby_data, cpv_value, &b_result);
        assert(b_result);

        if(b_less)
        {
            assert(pt_parent->_pt_left == NULL);
            pt_parent->_pt_left = pt_cur;
        }
        else
        {
            assert(pt_parent->_pt_right == NULL);
            pt_parent->_pt_right = pt_cur;
        }

        if(_rb_tree_get_color(pt_parent) == RED)
        {
            _rb_tree_rebalance(pt_rb_tree, pt_cur);
        }
    }

    return pt_cur;
}