/**
 * Test the first iterator is before the second.
 */
bool_t _avl_tree_iterator_before(_avl_tree_iterator_t it_first, _avl_tree_iterator_t it_second)
{
    _avl_tree_iterator_t it_iter;
    _avl_tree_iterator_t it_end;
    _avl_tree_t*         pt_avl_tree = NULL;

    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_first), it_first));
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_second), it_second));
    assert(_AVL_TREE_ITERATOR_TREE(it_first) == _AVL_TREE_ITERATOR_TREE(it_second));

    /* first iterator equal to second iterator */
    if (_AVL_TREE_ITERATOR_COREPOS(it_first) == _AVL_TREE_ITERATOR_COREPOS(it_second)) {
        return false;
    }
    /* else travel subtree for search second iterator */
    pt_avl_tree = _AVL_TREE_ITERATOR_TREE(it_first);
    it_end = _avl_tree_end(pt_avl_tree);
    for (it_iter = it_first;
         !_avl_tree_iterator_equal(it_iter, it_end);
         it_iter = _avl_tree_iterator_next(it_iter)) {
        if (_avl_tree_iterator_equal(it_iter, it_second)) {
            return true;
        }
    }

    return _avl_tree_iterator_equal(it_second, it_end) ? true : false;
}
/**
 * Return iterator reference previous element.
 */
_avl_tree_iterator_t _avl_tree_iterator_prev(_avl_tree_iterator_t it_iter)
{
    _avlnode_t* pt_prev = NULL;
    _avlnode_t* pt_cur = (_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter);

    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_avl_tree_iterator_equal(it_iter, _avl_tree_begin(_AVL_TREE_ITERATOR_TREE(it_iter))));

    /* previous end */
    if (_avl_tree_iterator_equal(it_iter, _avl_tree_end(_AVL_TREE_ITERATOR_TREE(it_iter)))) {
        _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)_AVL_TREE_ITERATOR_TREE(it_iter)->_t_avlroot._pt_right;
    } else {
        if (pt_cur->_pt_left != NULL) {
            /*
             *        A
             *       / \
             *      B   C
             *     / \   \
             *    D   E   F
             *       /
             *      G
             *  current  : A
             *  previous : E
             */
            pt_prev = pt_cur->_pt_left;
            while (pt_prev->_pt_right != NULL) {
                pt_prev = pt_prev->_pt_right;
            }

            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
        } else {
            /*
             *        A
             *       / \
             *      B   C
             *     /   / \
             *    D   E   F
             *       /
             *      G
             * 
             *  current  : G
             *  previous : A
             */
            pt_prev = pt_cur->_pt_parent;
            while (pt_cur == pt_prev->_pt_left) {
                pt_cur = pt_prev;
                pt_prev = pt_prev->_pt_parent;
            }

            /* 
             * there is no same special condition as next, because the begin 
             * iterator is the valid iterator 
             */
            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_prev;
        }
    }

    return it_iter;
}
/**
 * Test the two avl tree iterator are equal.
 */
bool_t _avl_tree_iterator_equal(_avl_tree_iterator_t it_first, _avl_tree_iterator_t it_second)
{
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_first), it_first));
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_second), it_second));
    assert(_AVL_TREE_ITERATOR_TREE(it_first) == _AVL_TREE_ITERATOR_TREE(it_second));

    return _AVL_TREE_ITERATOR_COREPOS(it_first) == _AVL_TREE_ITERATOR_COREPOS(it_second) ? true : false;
}
/**
 * Get data value pointer referenced by iterator.
 */
const void* _avl_tree_iterator_get_pointer(_avl_tree_iterator_t it_iter)
{
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_avl_tree_iterator_equal(it_iter, _avl_tree_end(_AVL_TREE_ITERATOR_TREE(it_iter))));

    /* char* */
    if (strncmp(_GET_AVL_TREE_TYPE_BASENAME(_AVL_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
        return (char*)string_c_str((string_t*)((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter))->_pby_data);
    } else {
        return ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter))->_pby_data;
    }
}
Example #5
0
/**
 * Tests if the two avl tree are equal.
 */
bool_t _avl_tree_equal(const _avl_tree_t* cpt_first, const _avl_tree_t* cpt_second)
{
    _avl_tree_iterator_t it_first;
    _avl_tree_iterator_t it_first_begin;
    _avl_tree_iterator_t it_first_end;
    _avl_tree_iterator_t it_second;
    _avl_tree_iterator_t it_second_begin;
    _avl_tree_iterator_t it_second_end;
    bool_t               b_less = false;
    bool_t               b_greater = false;

    assert(cpt_first != NULL);
    assert(cpt_second != NULL);
    assert(_avl_tree_is_inited(cpt_first));
    assert(_avl_tree_is_inited(cpt_second));
    assert(_avl_tree_same_type_ex(cpt_first, cpt_second));

    if (cpt_first == cpt_second) {
        return true;
    }

    /* test avl tree size */
    if (_avl_tree_size(cpt_first) != _avl_tree_size(cpt_second)) {
        return false;
    }

    it_first_begin = _avl_tree_begin(cpt_first);
    it_first_end = _avl_tree_end(cpt_first);
    it_second_begin = _avl_tree_begin(cpt_second);
    it_second_end = _avl_tree_end(cpt_second);

    /* test each element */
    for (it_first = it_first_begin, it_second = it_second_begin;
         !_avl_tree_iterator_equal(it_first, it_first_end) && !_avl_tree_iterator_equal(it_second, it_second_end);
         it_first = _avl_tree_iterator_next(it_first), it_second = _avl_tree_iterator_next(it_second)) {
        b_less = b_greater = _GET_AVL_TREE_TYPE_SIZE(cpt_first);
        _GET_AVL_TREE_TYPE_LESS_FUNCTION(cpt_first)(
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_first))->_pby_data,
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_second))->_pby_data, &b_less);
        _GET_AVL_TREE_TYPE_LESS_FUNCTION(cpt_first)(
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_second))->_pby_data,
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_first))->_pby_data, &b_greater);
        if (b_less || b_greater) {
            return false;
        }
    }
    assert(_avl_tree_iterator_equal(it_first, it_first_end) && _avl_tree_iterator_equal(it_second, it_second_end));

    return true;
}
Example #6
0
/**
 * Test iterator referenced data is within the avl tree.
 */
bool_t _avl_tree_iterator_belong_to_avl_tree(const _avl_tree_t* cpt_avl_tree, _avl_tree_iterator_t it_iter)
{
    assert(cpt_avl_tree != NULL);
    assert(_avl_tree_is_inited(cpt_avl_tree));
    assert(_AVL_TREE_ITERATOR_COREPOS(it_iter) != NULL);
    assert(_AVL_TREE_ITERATOR_TREE(it_iter) == cpt_avl_tree);

    /* if iterator is end */
    if (_AVL_TREE_ITERATOR_COREPOS(it_iter) == (_byte_t*)&cpt_avl_tree->_t_avlroot) {
        return true;
    } else {
        /* travel avl tree for search the pointer */
        return _avl_tree_avlnode_belong_to_avl_tree(
            cpt_avl_tree->_t_avlroot._pt_parent, (_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter));
    }
}
/**
 * Get data value pointer referenced by iterator, but ignore char*.
 */
const void* _avl_tree_iterator_get_pointer_ignore_cstr(_avl_tree_iterator_t it_iter)
{
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_avl_tree_iterator_equal(it_iter, _avl_tree_end(_AVL_TREE_ITERATOR_TREE(it_iter))));

    return ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter))->_pby_data;
}
/**
 * Get data value referenced by iterator.
 */
void _avl_tree_iterator_get_value(_avl_tree_iterator_t it_iter, void* pv_value)
{
    assert(pv_value != NULL);
    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_avl_tree_iterator_equal(it_iter, _avl_tree_end(_AVL_TREE_ITERATOR_TREE(it_iter))));

    /* char* */
    if (strncmp(_GET_AVL_TREE_TYPE_BASENAME(_AVL_TREE_ITERATOR_TREE(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
        *(char**)pv_value = (char*)string_c_str((string_t*)((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter))->_pby_data);
    } else {
        bool_t b_result = _GET_AVL_TREE_TYPE_SIZE(_AVL_TREE_ITERATOR_TREE(it_iter));
        _GET_AVL_TREE_TYPE_COPY_FUNCTION(_AVL_TREE_ITERATOR_TREE(it_iter))(
            pv_value, ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter))->_pby_data, &b_result);
        assert(b_result);
    }
}
Example #9
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;
}
Example #10
0
/**
 * Find specific element.
 */
_avl_tree_iterator_t _avl_tree_find(const _avl_tree_t* cpt_avl_tree, const void* cpv_value)
{
    _avl_tree_iterator_t it_iter;

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

    _AVL_TREE_ITERATOR_TREE_POINTER(it_iter) = (void*)cpt_avl_tree;
    _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)_avl_tree_find_value(
        cpt_avl_tree, cpt_avl_tree->_t_avlroot._pt_parent, cpv_value);
    if (_AVL_TREE_ITERATOR_COREPOS(it_iter) == NULL) {
        _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)&cpt_avl_tree->_t_avlroot;
    }

    return it_iter;
}
Example #11
0
/**
 * Tests if the first avl tree is less than the second avl tree.
 */
bool_t _avl_tree_less(const _avl_tree_t* cpt_first, const _avl_tree_t* cpt_second)
{
    _avl_tree_iterator_t it_first;
    _avl_tree_iterator_t it_first_begin;
    _avl_tree_iterator_t it_first_end;
    _avl_tree_iterator_t it_second;
    _avl_tree_iterator_t it_second_begin;
    _avl_tree_iterator_t it_second_end;
    bool_t               b_result = false;

    assert(cpt_first != NULL);
    assert(cpt_second != NULL);
    assert(_avl_tree_is_inited(cpt_first));
    assert(_avl_tree_is_inited(cpt_second));
    assert(_avl_tree_same_type_ex(cpt_first, cpt_second));

    it_first_begin = _avl_tree_begin(cpt_first);
    it_first_end = _avl_tree_end(cpt_first);
    it_second_begin = _avl_tree_begin(cpt_second);
    it_second_end = _avl_tree_end(cpt_second);

    /* test each element */
    for (it_first = it_first_begin, it_second = it_second_begin;
         !_avl_tree_iterator_equal(it_first, it_first_end) && !_avl_tree_iterator_equal(it_second, it_second_end);
         it_first = _avl_tree_iterator_next(it_first), it_second = _avl_tree_iterator_next(it_second)) {
        b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_first);
        _GET_AVL_TREE_TYPE_LESS_FUNCTION(cpt_first)(
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_first))->_pby_data,
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_second))->_pby_data, &b_result);
        if (b_result) {
            return true;
        }
        b_result = _GET_AVL_TREE_TYPE_SIZE(cpt_first);
        _GET_AVL_TREE_TYPE_LESS_FUNCTION(cpt_first)(
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_second))->_pby_data,
            ((_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_first))->_pby_data, &b_result);
        if (b_result) {
            return false;
        }
    }

    return _avl_tree_size(cpt_first) < _avl_tree_size(cpt_second) ? true : false;
}
Example #12
0
_avl_tree_reverse_iterator_t _avl_tree_rend(const _avl_tree_t* cpt_avl_tree)
{
    _avl_tree_reverse_iterator_t it_newiterator = _create_avl_tree_iterator();

    assert(cpt_avl_tree != NULL);

    _AVL_TREE_ITERATOR_TREE_POINTER(it_newiterator) = (void*)cpt_avl_tree;
    _AVL_TREE_ITERATOR_COREPOS(it_newiterator) = (_byte_t*)&cpt_avl_tree->_t_avlroot;

    return it_newiterator;
}
/**
 * Create avl tree iterator.
 */
_avl_tree_iterator_t _create_avl_tree_iterator(void)
{
    _avl_tree_iterator_t it_iter;

    _AVL_TREE_ITERATOR_COREPOS(it_iter) = NULL;
    _AVL_TREE_ITERATOR_TREE_POINTER(it_iter) = NULL;

    _ITERATOR_CONTAINER(it_iter) = NULL;

    return it_iter;
}
Example #14
0
/**
 * Return an iterator that addresses the first element in the avl tree.
 */
_avl_tree_iterator_t _avl_tree_begin(const _avl_tree_t* cpt_avl_tree)
{
    _avl_tree_iterator_t it_begin = _create_avl_tree_iterator();

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

    _AVL_TREE_ITERATOR_TREE_POINTER(it_begin) = (void*)cpt_avl_tree;
    _AVL_TREE_ITERATOR_COREPOS(it_begin) = (_byte_t*)cpt_avl_tree->_t_avlroot._pt_left;

    return it_begin;
}
Example #15
0
/**
 * Return an iterator that addresses the location succeeding the last element in the avl tree.
 */
_avl_tree_iterator_t _avl_tree_end(const _avl_tree_t* cpt_avl_tree)
{
    _avl_tree_iterator_t it_end = _create_avl_tree_iterator();

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

    _AVL_TREE_ITERATOR_TREE_POINTER(it_end) = (void*)cpt_avl_tree;
    _AVL_TREE_ITERATOR_COREPOS(it_end) = (_byte_t*)&cpt_avl_tree->_t_avlroot;

    return it_end;
}
Example #16
0
/**
 * Inserts an element into a avl tree.
 */
_avl_tree_iterator_t _avl_tree_insert_equal(_avl_tree_t* pt_avl_tree, const void* cpv_value)
{
    _avl_tree_insert_result_t t_result;
    _avl_tree_iterator_t      it_iter = _create_avl_tree_iterator();

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

    t_result = _avl_tree_insert_avlnode(pt_avl_tree, pt_avl_tree->_t_avlroot._pt_parent, cpv_value);
    assert(t_result._pt_adjust != NULL && t_result._pt_new != NULL);

    pt_avl_tree->_t_avlroot._pt_parent = t_result._pt_adjust;
    pt_avl_tree->_t_avlroot._pt_parent->_pt_parent = &pt_avl_tree->_t_avlroot;
    pt_avl_tree->_t_avlroot._pt_left = _avl_tree_get_min_avlnode(pt_avl_tree->_t_avlroot._pt_parent);
    pt_avl_tree->_t_avlroot._pt_right = _avl_tree_get_max_avlnode(pt_avl_tree->_t_avlroot._pt_parent);
    pt_avl_tree->_t_nodecount++;

    _AVL_TREE_ITERATOR_TREE_POINTER(it_iter) = pt_avl_tree;
    _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)t_result._pt_new;

    return it_iter;
}
/**
 * Return iterator reference next element.
 */
_avl_tree_iterator_t _avl_tree_iterator_next(_avl_tree_iterator_t it_iter)
{
    _avlnode_t* pt_next = NULL;  /* next pos */
    _avlnode_t* pt_cur = (_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_iter);

    assert(_avl_tree_iterator_belong_to_avl_tree(_AVL_TREE_ITERATOR_TREE(it_iter), it_iter));
    assert(!_avl_tree_iterator_equal(it_iter, _avl_tree_end(_AVL_TREE_ITERATOR_TREE(it_iter))));

    if (pt_cur->_pt_right != NULL) {
        /*
         *        A
         *       / \
         *      B   C
         *     / \   \
         *    D   E   F
         *       /
         *      G
         *  current : B
         *  next    : G
         */
        pt_next = pt_cur->_pt_right;
        while (pt_next->_pt_left != NULL) {
            pt_next = pt_next->_pt_left;
        }

        _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_next;
    } else {
        /*
         *     avlroot
         *        |
         *        A
         *       / \
         *      B   C
         *     / \   \
         *    D   E   F
         *       /
         *      G
         */
        pt_next = pt_cur->_pt_parent;
        while (pt_cur == pt_next->_pt_right) {
            pt_cur = pt_next;
            pt_next = pt_next->_pt_parent;
        }
        /* 
         * this is special condition, when the next pos is root's parent.
         * when the avl tree has only one node, this condition is came.
         */
        if (pt_cur->_pt_right != pt_next) {
            /*
             * current : E or F
             * next    : A or avlroot
             */
            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_next;
        } else {
            /* here is special condition */
            /*
             *   avlroot
             *      |
             *      A
             */
            _AVL_TREE_ITERATOR_COREPOS(it_iter) = (_byte_t*)pt_cur;
        }
    }

    return it_iter;
}
Example #18
0
/*
 * Erase an element in an avl tree from specificed position.
 */
void _avl_tree_erase_pos(_avl_tree_t* pt_avl_tree, _avl_tree_iterator_t it_pos)
{
    _avlnode_t* pt_parent = NULL;
    _avlnode_t* pt_cur = NULL;
    bool_t      b_result = false;

    assert(pt_avl_tree != NULL);
    assert(_avl_tree_is_inited(pt_avl_tree));
    assert(_avl_tree_iterator_belong_to_avl_tree(pt_avl_tree, it_pos));
    assert(!_avl_tree_iterator_equal(it_pos, _avl_tree_end(pt_avl_tree)));
    
    pt_cur = (_avlnode_t*)_AVL_TREE_ITERATOR_COREPOS(it_pos);
    pt_parent = pt_cur->_pt_parent;

    /* delete node X express deleting */
    if (pt_cur->_pt_left == NULL && pt_cur->_pt_right == NULL) {
        if (pt_parent == &pt_avl_tree->_t_avlroot) {
            /*
             *  P       P
             *  |   =>   
             *  X
             */
            pt_parent->_pt_parent = NULL;
        } else if (pt_cur == pt_parent->_pt_left) {
            /*
             *    P       P
             *   /   =>   
             *  X
             */
            pt_parent->_pt_left = NULL;
        } else {
            /*
             *   P         P
             *    \   =>  
             *     X
             */
            pt_parent->_pt_right = NULL;
        }
    } else if (pt_cur->_pt_left != NULL && pt_cur->_pt_right == NULL) {
        if (pt_parent == &pt_avl_tree->_t_avlroot) {
            /*
             *   P          P
             *   |          |
             *   X     =>   L
             *  /
             * L
             */
            pt_parent->_pt_parent = pt_cur->_pt_left;
            pt_parent->_pt_parent->_pt_parent = pt_parent;
        } else if (pt_cur == pt_parent->_pt_left) {
            /*
             *     P          P
             *    /          /
             *   X     =>   L
             *  /
             * L
             */
            pt_parent->_pt_left = pt_cur->_pt_left;
            pt_parent->_pt_left->_pt_parent = pt_parent;
        } else {
            /*
             *  P           P
             *   \           \
             *    X   =>      L
             *   /
             *  L
             */
            pt_parent->_pt_right = pt_cur->_pt_left;
            pt_parent->_pt_right->_pt_parent = pt_parent;
        }
    } else if (pt_cur->_pt_left == NULL && pt_cur->_pt_right != NULL) {
        if (pt_parent == &pt_avl_tree->_t_avlroot) {
            /*
             *     P             P
             *     |             |
             *     X     =>      R
             *      \
             *       R
             */
            pt_parent->_pt_parent = pt_cur->_pt_right;
            pt_parent->_pt_parent->_pt_parent = pt_parent;
        } else if (pt_cur == pt_parent->_pt_right) {
            /*
             *   P             P
             *    \             \
             *     X     =>      R
             *      \
             *       R
             */
            pt_parent->_pt_right = pt_cur->_pt_right;
            pt_parent->_pt_right->_pt_parent = pt_parent;
        } else {
            /*
             *    P              R
             *   /              /
             *  X       =>     R
             *   \
             *    R
             */
            pt_parent->_pt_left = pt_cur->_pt_right;
            pt_parent->_pt_left->_pt_parent = pt_parent;
        }
    } else {
        _avlnode_t* pt_parenttmp = NULL;
        _avlnode_t* pt_curtmp = NULL;

        if (pt_parent == &pt_avl_tree->_t_avlroot) {
            pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right);
            if (pt_cur == pt_curtmp->_pt_parent) {
                /*
                 *     P              P
                 *     |              | 
                 *     X       =>     B
                 *    / \            / \
                 *   A   B          A   C
                 *        \
                 *         C
                 */
                /* pt_curtmp express B */
                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_parent = pt_curtmp;

                pt_parent = pt_curtmp;
            } else {
                /*
                 *     P              P
                 *     |              | 
                 *     X       =>     S
                 *    / \            / \
                 *   A   B          A   B
                 *      / \            / \
                 *     S   C          D   C
                 *      \
                 *       D
                 */
                /* pt_curtmp express S; pt_parenttmp express B */
                pt_parenttmp = pt_curtmp->_pt_parent;
                pt_parenttmp->_pt_left = pt_curtmp->_pt_right;
                if (pt_parenttmp->_pt_left != NULL) {
                    pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp;
                }

                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_right = pt_cur->_pt_right;
                pt_curtmp->_pt_right->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_parent = pt_curtmp;

                pt_parent = pt_parenttmp;
            }
        } else if (pt_cur == pt_parent->_pt_left) {
            pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right);
            if (pt_cur == pt_curtmp->_pt_parent) {
                /*
                 *       P              P
                 *      /              / 
                 *     X       =>     B
                 *    / \            / \
                 *   A   B          A   C
                 *        \
                 *         C
                 */
                /* pt_curtmp express B */
                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_left = pt_curtmp;

                pt_parent = pt_curtmp;
            } else {
                /*
                 *       P              P
                 *      /              / 
                 *     X       =>     S
                 *    / \            / \
                 *   A   B          A   B
                 *      / \            / \
                 *     S   C          D   C
                 *      \
                 *       D
                 */
                /* pt_curtmp express S; pt_parenttmp express B */
                pt_parenttmp = pt_curtmp->_pt_parent;
                pt_parenttmp->_pt_left = pt_curtmp->_pt_right;
                if (pt_parenttmp->_pt_left != NULL) {
                    pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp;
                }

                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_right = pt_cur->_pt_right;
                pt_curtmp->_pt_right->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_left = pt_curtmp;

                pt_parent = pt_parenttmp;
            }
        } else {
            pt_curtmp = _avl_tree_get_min_avlnode(pt_cur->_pt_right);
            if (pt_cur == pt_curtmp->_pt_parent) {
                /*
                 *      P            P
                 *       \            \
                 *        X     =>     B
                 *       / \          / \
                 *      A   B        A   C
                 *           \
                 *            C
                 */
                /* pt_curtmp express B */
                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_right = pt_curtmp;

                pt_parent = pt_curtmp;
            } else {
                /*
                 *      P            P
                 *       \            \
                 *        X     =>     S
                 *       / \          / \
                 *      A   B        A   B
                 *         / \          / \
                 *        C   D        C   D
                 *       / \          / \
                 *      S   E        F   E
                 *       \
                 *        F
                 */
                /* pt_curtmp express S; pt_parenttmp express C */
                pt_parenttmp = pt_curtmp->_pt_parent;
                pt_parenttmp->_pt_left = pt_curtmp->_pt_right;
                if (pt_parenttmp->_pt_left != NULL) {
                    pt_parenttmp->_pt_left->_pt_parent = pt_parenttmp;
                }

                pt_curtmp->_pt_left = pt_cur->_pt_left;
                pt_curtmp->_pt_left->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_right = pt_cur->_pt_right;
                pt_curtmp->_pt_right->_pt_parent = pt_curtmp;
                pt_curtmp->_pt_parent = pt_cur->_pt_parent;
                pt_curtmp->_pt_parent->_pt_right = pt_curtmp;

                pt_parent = pt_parenttmp;
            }
        }
    }

    /* rebalance until to root */
    if (pt_parent != &pt_avl_tree->_t_avlroot) {
        _avlnode_t* pt_newcur = pt_parent;
        pt_parent = pt_newcur->_pt_parent;
        while (pt_parent != &pt_avl_tree->_t_avlroot) {
            if (pt_newcur == pt_parent->_pt_left) {
                pt_parent->_pt_left = _avl_tree_rebalance(pt_parent->_pt_left);
                pt_parent->_pt_left->_pt_parent = pt_parent;
            } else {
                pt_parent->_pt_right = _avl_tree_rebalance(pt_parent->_pt_right);
                pt_parent->_pt_right->_pt_parent = pt_parent;
            }

            pt_newcur = pt_parent;
            pt_parent = pt_newcur->_pt_parent;
        }
    }

    /* rebalance root */
    if (pt_parent->_pt_parent != NULL) {
        pt_parent->_pt_parent = _avl_tree_rebalance(pt_parent->_pt_parent);
        pt_parent->_pt_parent->_pt_parent = pt_parent;
    }

    /* destroy node */
    b_result = _GET_AVL_TREE_TYPE_SIZE(pt_avl_tree);
    _GET_AVL_TREE_TYPE_DESTROY_FUNCTION(pt_avl_tree)(pt_cur->_pby_data, &b_result);
    assert(b_result);
    _alloc_deallocate(&pt_avl_tree->_t_allocator, pt_cur,
        _AVL_TREE_NODE_SIZE(_GET_AVL_TREE_TYPE_SIZE(pt_avl_tree)), 1);
    pt_avl_tree->_t_nodecount--;
    if (pt_avl_tree->_t_nodecount == 0) {
        pt_avl_tree->_t_avlroot._pt_parent = NULL;
        pt_avl_tree->_t_avlroot._pt_left = &pt_avl_tree->_t_avlroot;
        pt_avl_tree->_t_avlroot._pt_right = &pt_avl_tree->_t_avlroot;
    } else {
        pt_avl_tree->_t_avlroot._pt_left = _avl_tree_get_min_avlnode(pt_avl_tree->_t_avlroot._pt_parent);
        pt_avl_tree->_t_avlroot._pt_right = _avl_tree_get_max_avlnode(pt_avl_tree->_t_avlroot._pt_parent);
    }
}