Пример #1
0
/* *
 * 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);
    }
}
Пример #2
0
/*
* 	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
}
Пример #4
0
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);
}
Пример #5
0
/* *
 * 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;
}