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