/** * 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; } }
/** * 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; }
/** * 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); } }
/** * 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; }
/** * 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; }
/** * 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; }
_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; }
/** * 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; }
/** * 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; }
/** * 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; }
/* * 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); } }