/* 删除任意值辅助函数 */ rbtree_node _rbtree_delete(rbtree_node h,int key){ if(key < h->key){ if( !is_red(h->left) && !is_red(h->left->left)) h = move_red_left(h); h->left = _rbtree_delete(h->left,key); }else{ if( is_red(h->left) ) h = rotate_right(h); if( key == h->key && h->right == NULL){ free(h); return NULL; } if( !is_red(h->right) && !is_red(h->right->left) ) h = move_red_right(h); if( key == h->key ){ //TODO:获得最小值 rbtree_node x = _rbtree_min(h->right); h->key = x->key; h->val = x->val; h->right = _rbtree_delete_min(h->right); }else{ h->right = _rbtree_delete(h->right,key); } } }
/* * Deletes the node in the subtree having an arbitrary key. (Note that "deletes" means "removes from the tree." * No memory delete operation is actually performed.) An O(log n) operation. * * Parameters: * - ptree = Pointer to the tree head structure, containing the compare function. * - ptnCurrent = Pointer to the root of the current subtree we're deleting from. * - key = Key value we're deleting from the tree. It is assumed that this key value exists in the subtree. * * Returns: * Pointer to the root of the subtree after the node has been deleted. * * N.B.: * This function is recursive; however, the nature of the tree guarantees that the stack space consumed * by its stack frames (and those of delete_min, where we call it) will be O(log n). */ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREEKEY key) { register TREEKEY keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); register int cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); if (cmp < 0) { /* hunt down the left subtree */ if (!rbtIsRed(ptnCurrent->ptnLeft) && !rbtIsRed(ptnCurrent->ptnLeft->ptnLeft)) ptnCurrent = move_red_left(ptnCurrent); ptnCurrent->ptnLeft = delete_from_under(ptree, ptnCurrent->ptnLeft, key); } else { if (rbtIsRed(ptnCurrent->ptnLeft)) { ptnCurrent = rotate_right(ptnCurrent); keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); } if ((cmp == 0) && !rbtNodeRight(ptnCurrent)) return ptnCurrent->ptnLeft; /* degenerate case */ if ( !rbtIsRed(rbtNodeRight(ptnCurrent)) && (!rbtNodeRight(ptnCurrent) || !rbtIsRed(rbtNodeRight(ptnCurrent)->ptnLeft))) { ptnCurrent = move_red_right(ptnCurrent); keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent)); cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent); } if (cmp == 0) { /* * Here we find the minimum node in the right subtree, unlink it, and link it into place in place of * ptnCurrent (i.e. node pointed to by ptnCurrent should no longer be referenced). We inherit the * child pointers and color of ptnCurrent (minus the reference from the right-hand tree where applicable). */ register PRBTREENODE ptnMin = find_min(rbtNodeRight(ptnCurrent)); rbtSetNodeRight(ptnMin, delete_min(rbtNodeRight(ptnCurrent))); ptnMin->ptnLeft = ptnCurrent->ptnLeft; rbtSetNodeColor(ptnMin, rbtNodeColor(ptnCurrent)); ptnCurrent = ptnMin; } else /* hunt down the right subtree */ rbtSetNodeRight(ptnCurrent, delete_from_under(ptree, rbtNodeRight(ptnCurrent), key)); } return fix_up(ptnCurrent); }
/* 删除最大值的赋值函数 */ rbtree_node _rbtree_delete_max(rbtree_node root){ if( is_red(root->left) ){ root = rotate_right(root); } if( root->right == NULL ){ free(root); return NULL; } if( !is_red(root->right) && !is_red(root->right->left) ){ root = move_red_right(root); } root->right = _rbtree_delete_max(root->right); return fixup(root); }
static rbtree_node* delete_max(rbtree_node *h, VALUE *deleted_value) { if ( isred(h->left) ) h = rotate_right(h); if ( !h->right ) { *deleted_value = h->value; free(h); return NULL; } if ( !isred(h->right) && !isred(h->right->left) ) h = move_red_right(h); h->right = delete_max(h->right, deleted_value); return fixup(h); }