/* * * rb_delete - deletes @node from @tree, and calls rb_delete_fixup to * restore red-black properties. * */ void rb_delete(rb_tree *tree, rb_node *node) { rb_node *x, *y, *z = node; rb_node *nil = tree->nil, *root = tree->root; y = (z->left == nil || z->right == nil) ? z : rb_tree_successor(tree, z); x = (y->left != nil) ? y->left : y->right; assert(y != root && y != nil); x->parent = y->parent; if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } bool need_fixup = !(y->red); if (y != z) { if (z == z->parent->left) { z->parent->left = y; } else { z->parent->right = y; } z->left->parent = z->right->parent = y; *y = *z; } if (need_fixup) { rb_delete_fixup(tree, x); } }
/* * most principle is that: * node is replaced by p * p is replaced by q */ static int _rb_tree_erase(struct rb_root *root,struct rb_node *node) { struct rb_node *p; struct rb_node *q; struct rb_node *parent; if(!node->left || !node->right) p = node; else if(rb_tree_successor(root,node,&p)<0) return -1; // printf("node(%ld) successor:%ld\n",node->key,p->key); if(p->left) q = p->left; else q = p->right; if(q) q->parent = p->parent; if(!p->parent) root->root = q; else if(p->parent->left == p) p->parent->left = q; else p->parent->right = q; parent = p->parent; if(p != node) { //change parent p->parent = node->parent; if(!node->parent) root->root = p; else if(node->parent->left == node) node->parent->left = p; else node->parent->right = p; //change left child if(node->left && node->right != p) { p->left = node->left; node->left->parent = p; } //change right child if(node->right && node->right != p) { p->right = node->right; node->right->parent = p; } //make node clean init_rb_node(node,node->key); } root->len --; //make up color // if(node->color == BLACK) // __rb_tree_erase_fixup(root,parent,q); return 0; }
void rb_tree_delete(rb_red_blk_tree* tree, rb_red_blk_node* z){ rb_red_blk_node* y; rb_red_blk_node* x; rb_red_blk_node* nil=tree->nil; rb_red_blk_node* root=tree->root; y= ((z->left == nil) || (z->right == nil)) ? z : rb_tree_successor(tree,z); x= (y->left == nil) ? y->right : y->left; if (root == (x->parent = y->parent)) { /* assignment of y->p to x->p is intentional */ root->left=x; } else { if (y == y->parent->left) { y->parent->left=x; } else { y->parent->right=x; } } if (y != z) { /* y should not be nil in this case */ #ifdef DEBUG_ASSERT Assert( (y!=tree->nil),"y is nil in RBDelete\n"); #endif /* y is the node to splice out and x is its child */ if (!(y->red)) RBDeleteFixUp(tree,x); tree->key_dtor_func(z->key); tree->info_dtor_func(z->info); y->left=z->left; y->right=z->right; y->parent=z->parent; y->red=z->red; z->left->parent=z->right->parent=y; if (z == z->parent->left) { z->parent->left=y; } else { z->parent->right=y; } free(z); } else { tree->key_dtor_func(y->key); tree->info_dtor_func(y->info); if (!(y->red)) RBDeleteFixUp(tree,x); free(y); } #ifdef DEBUG_ASSERT Assert(!tree->nil->red,"nil not black in RBDelete"); #endif }
static void rb_tree_delete(rb_tree_t *tree, rb_tree_node_t *z) { rb_tree_node_t *y = NULL; rb_tree_node_t *x = NULL; if (IS_NIL(tree, z->left) || IS_NIL(tree, z->right)) { y = z; } else { y = rb_tree_successor(tree, z); } if (IS_NIL(tree, y->left)) { x = y->right; } else { x = y->left; } x->parent = y->parent; if (IS_NIL(tree, y->parent)) { tree->head = x; } else { if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } } if (y != z) { /* z->left = y->left; */ /* z->right = y->right; */ /* z->parent = y->parent; */ /* z->color = y->color; */ z->key = y->key; z->count = y->count; } if (y->color == BLACK) { rb_tree_delete_fixup(tree, x); } free(y); }
/* * * rb_node_next - returns the successor node of @node in @tree, * or 'NULL' if no successor exists. * */ rb_node * rb_node_next(rb_tree *tree, rb_node *node) { rb_node *next = rb_tree_successor(tree, node); return (next != tree->nil) ? next : NULL; }