/* 删除任意值辅助函数 */ 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 leftmost node in the subtree. (Note that "deletes" means "removes from the tree." No memory * delete operation is actually performed.) * * Parameters: * - ptn = Pointer to root of subtree to have its leftmost node deleted. * * Returns: * Pointer to root of subtree after having the leftmost node deleted. * * N.B.: * This function is recursive; however, the nature of the tree guarantees that the stack space consumed * by its stack frames will be O(log n). */ static PRBTREENODE delete_min(PRBTREENODE ptn) { if (!(ptn->ptnLeft)) return rbtNodeRight(ptn); if (!rbtIsRed(ptn->ptnLeft) && !rbtIsRed(ptn->ptnLeft->ptnLeft)) ptn = move_red_left(ptn); ptn->ptnLeft = delete_min(ptn->ptnLeft); return fix_up(ptn); }
static rbtree_node* delete_min(rbtree_node *h, VALUE *deleted_value) { if ( !h->left ) { if(deleted_value) *deleted_value = h->value; free(h); return NULL; } if ( !isred(h->left) && !isred(h->left->left) ) h = move_red_left(h); h->left = delete_min(h->left, deleted_value); return fixup(h); }
/* * 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_min(rbtree_node root){ if(root->left==NULL){ free(root); return NULL; } /* * 如果向下两个任何一个是红色的, * 就不用把红色传递下去,因为下面的红色可以 * 用来构成最后删除结点的红色. * red * / \ * black black * / * black * */ if( !is_red(root->left) && !is_red(root->left->left) ){ root = move_red_left(root); } root->left = _rbtree_delete_min(root->left); return fixup(root); }