Beispiel #1
0
/*
如果需要删除的节点有两个儿子,那么问题可以被转化成删除另一个只有一个儿子的节点的问题(为了表述方便,这里所指的儿子,为非叶子节点的儿子)。对于二叉查找树,在删除带有两个非叶子儿子的节点的时候,我们找到要么在它的左子树中的最大元素、要么在它的右子树中的最小元素,并把它的值转移到要删除的节点中(如在这里所展示的那样)。我们接着删除我们从中复制出值的那个节点,它必定有少于两个非叶子的儿子。因为只是复制了一个值而不违反任何属性,这就把问题简化为如何删除最多有一个儿子的节点的问题。它不关心这个节点是最初要删除的节点还是我们从中复制出值的那个节点。
在本文余下的部分中,我们只需要讨论删除只有一个儿子的节点(如果它两个儿子都为空,即均为叶子,我们任意将其中一个看作它的儿子)。如果我们删除一个红色节点(此时该节点的儿子将都为叶子节点),它的父亲和儿子一定是黑色的。所以我们可以简单的用它的黑色儿子替换它,并不会破坏属性3和4。通过被删除节点的所有路径只是少了一个红色节点,这样可以继续保证属性5。另一种简单情况是在被删除节点是黑色而它的儿子是红色的时候。如果只是去除这个黑色节点,用它的红色儿子顶替上来的话,会破坏属性5,但是如果我们重绘它的儿子为黑色,则曾经通过它的所有路径将通过它的黑色儿子,这样可以继续保持属性5。
需要进一步讨论的是在要删除的节点和它的儿子二者都是黑色的时候,这是一种复杂的情况。我们首先把要删除的节点替换为它的儿子。出于方便,称呼这个儿子为N(在新的位置上),称呼它的兄弟(它父亲的另一个儿子)为S
*/
rb_node_t *rb_erase(key_t key, rb_node_t *root)
{
	rb_node_t *child;	
	rb_node_t *parent;
	rb_node_t *old; //要删除的节点的copy
	rb_node_t *left;
	rb_node_t *node;//要删除的节点

	color_t color;

	if (!(node = rb_search_auxiliary(key, root, NULL))) {
		printf("key is not exist !/n");
		return root;
	}		

	old = node; 
	
	if (node->left && node->right) { //当要删除的节点的左右子节点都不为NULL时
		node = node->right;//本规则是取药删除节点的右子树中最小的节点
		while ((left = node->left) != NULL) {
			node = left;
		}
//找到右子树中的最小节点,并取其右孩子赋值给child
		child = node->right;
		parent = node->parent;//获取最小节点的父节点
		color = node->color; //获取最小节点的color

		if (child) {
			child->parent = parent;
		}

		if (parent) {
			if (parent->left == node) {
				parent->left = child;
			}else {
				parent->right = child;
			}
		}else {
			root = child;
		}

		if (node->parent == old) {
			parent = node;
		}

		node->parent = old->parent;
		node->color = old->color;
		node->right = old->right;
		node->left = old->left;

		if (old->parent) {
			if (old->parent->left == old) {
				old->parent->left = node;
			}else {
				old->parent->right = node;
			}
		}else {
			root = node;
		}
		
		old->left->parent = node;

		if (old->right) {
			old->right->parent = node;
		}
	}else {
		if (!node->left) {
			child = node->right;
		}else if (!node->right) {
			child = node->left;
		}

		parent = node->parent;
		color = node->color;

		if (child) {
			child->parent = parent;
		}
	
		if (parent) {
			if (parent->left == node) {
				parent->left = child;
			}else {
				parent->right = child;
			}
		}else {
			root = child;
		}
	}
	free(old);
	
	if (color == BLACK) {
		root = rb_erase_rebalance(child, parent, root);
	}

	return root;
}
Beispiel #2
0
void
rb_erase (rb_node_t * node, rb_node_t ** root)
{
  rb_node_t *child, *parent;
  int color;

  if (!node->rb_left)
    child = node->rb_right;
  else if (!node->rb_right)
    child = node->rb_left;
  else
    {
      rb_node_t *old = node, *left;

      node = node->rb_right;
      while ((left = node->rb_left))
	node = left;
      child = node->rb_right;
      parent = node->rb_parent;
      color = node->rb_color;

      if (child)
	child->rb_parent = parent;
      if (parent)
	{
	  if (parent->rb_left == node)
	    parent->rb_left = child;
	  else
	    parent->rb_right = child;
	}
      else
	*root = child;

      if (node->rb_parent == old)
	parent = node;
      node->rb_parent = old->rb_parent;
      node->rb_color = old->rb_color;
      node->rb_right = old->rb_right;
      node->rb_left = old->rb_left;

      if (old->rb_parent)
	{
	  if (old->rb_parent->rb_left == old)
	    old->rb_parent->rb_left = node;
	  else
	    old->rb_parent->rb_right = node;
	}
      else
	*root = node;

      old->rb_left->rb_parent = node;
      if (old->rb_right)
	old->rb_right->rb_parent = node;

      if (color == RB_BLACK)
	rb_erase_rebalance (child, parent, root);

      return;
    }

  parent = node->rb_parent;
  color = node->rb_color;

  if (child)
    child->rb_parent = parent;
  if (parent)
    {
      if (parent->rb_left == node)
	parent->rb_left = child;
      else
	parent->rb_right = child;
    }
  else
    *root = child;

  if (color == RB_BLACK)
    rb_erase_rebalance (child, parent, root);
}
Beispiel #3
0
static void rb_erase_by_node( RBTree *rbt, RBTreeNode *node )
{
	unsigned char color;
	RBTreeNode *parent;
	RBTreeNode *old = node;
	RBTreeNode *child = NULL;
	RBTreeNode *root = rbt->root;
	if( node->left && node->right ) {
		RBTreeNode *left;
		node = node->right;
		while( (left = node->left) != NULL ) {
			node = left;
		}
		child = node->right;
		parent = node->parent;
		color = node->color;

		if( child ) {
			child->parent = parent;
		}
		if( parent ) {
			if( parent->left == node ) {
				parent->left = child;
			} else {
				parent->right = child;
			}
		} else {
			root = child;
		}

		if( node->parent == old ) {
			parent = node;
		}

		node->parent = old->parent;
		node->color = old->color;
		node->right = old->right;
		node->left = old->left;

		if( old->parent ) {
			if( old->parent->left == old ) {
				old->parent->left = node;
			} else {
				old->parent->right = node;
			}
		} else {
			root = node;
		}

		old->left->parent = node;
		if( old->right ) {
			old->right->parent = node;
		}
	} else {
		if( !node->left ) {
			child = node->right;
		} else if( !node->right ) {
			child = node->left;
		}
		parent = node->parent;
		color = node->color;

		if( child ) {
			child->parent = parent;
		}
		if( parent ) {
			if( parent->left == node ) {
				parent->left = child;
			} else {
				parent->right = child;
			}
		} else {
			root = child;
		}
	}

	if( rbt->destroy && old->data ) {
		rbt->destroy( old->data );
	}
	free( old );
	if( color == BLACK ) {
		/* 恢复红黑树性质 */
		root = rb_erase_rebalance( child, parent, root );
	}
	rbt->root = root;
	rbt->total_node -= 1;
}
Beispiel #4
0
/** 删除红黑树中的结点 */
static int
rb_erase( rb_tree_t *rbt, mem_data_t *data, rb_data_type_t type )  
{
	rb_color_t color;
	rb_node_t *root, *child, *parent, *old, *left, *node; 

	root = rbt->root;
	/* 查找要删除的结点 */
	node = rb_search_auxiliary( root, data, type, NULL );
	if( !node ) {
		return -1;  
	}
	old = node;
	if (node->left && node->right) {
		node = node->right;  
		while ((left = node->left) != NULL) {  
			node = left;  
		}  
		child = node->right;  
		parent = node->parent;  
		color = node->color;  
	
		if (child) {  
			child->parent = parent;  
		}  
		if (parent) {  
			if (parent->left == node) {  
				parent->left = child;  
			} else {  
				parent->right = child;  
			}  
		} else {  
			root = child;  
		}  
	
		if (node->parent == old) {  
			parent = node;  
		}  
	
		node->parent = old->parent;  
		node->color = old->color;  
		node->right = old->right;  
		node->left = old->left;  
	
		if (old->parent) {  
			if (old->parent->left == old) {  
				old->parent->left = node;  
			} else {  
				old->parent->right = node;  
			}  
		} else {  
			root = node;  
		}  
	
		old->left->parent = node;  
		if (old->right) {  
			old->right->parent = node;  
		}  
	} else {  
		if (!node->left) {  
			child = node->right;  
		} else if (!node->right) {  
			child = node->left;  
		}  
		parent = node->parent;  
		color = node->color;  
	
		if (child) {  
			child->parent = parent;  
		}  
		if (parent) {  
			if (parent->left == node) {  
				parent->left = child;  
			} else {  
				parent->right = child;  
			}  
		} else {  
			root = child;  
		}  
	}
   
	free(old);  

	if (color == BLACK) {
		/* 恢复红黑树性质 */
		root = rb_erase_rebalance( child, parent, root );
	}

	rbt->root = root;
	rbt->total_node -= 1;
	return 0;  
}
Beispiel #5
0
//六、红黑树的删除
//------------------------------------------------------------
//红黑树的删除结点
rb_node_t* rb_erase(key_t key, rb_node_t *root){
	rb_node_t *child, *parent, *old, *left, *node;
	color_t color;

	if(!(node = rb_search_auxiliary(key, root, NULL))){//调用rb_search_auxiliary查找要删除的结点
		printf("key %d is not exist!/n", key);
		return root;
	}

	old = node;

	if(node->left && node->right){
		node = node->right;
		while(left = node->left){
			node = left;
		}
		child = node->right;
		parent = node->parent;
		color = node->color;

		if(child){
			child->parent = parent;
		}
		if(parent){
			if(parent->left == node){
				parent->left = child;
			}else{
				parent->right = child;
			}
		}else{
			root = child;
		}

		if(node->parent == old){
			parent = node;
		}

		node->parent = old->parent;
		node->color = old->color;
		node->right = old->right;
		node->left = old->left;

		if(old->parent){
			if(old->parent->left == old){
				old->parent->left = node;
			}else{
				old->parent->right = node;
			}
		}else{
			root = node;
		}

		old->left->parent = node;
		if(old->right){
			old->right->parent = node;
		}
	}else{
		if(!node->left){
			child = node->right;
		}else if (!node->right){
			child = node->left;
		}
		parent = node->parent;
		color = node->color;

		if(child){
			child->parent = parent;
		}
		if(parent){
			if(parent->left == node){
				parent->left = child;
			}else{
				parent->right = child;
			}
		}else{
			root = child;
		}
	}

	free(old);

	if(color == BLACK){
		root = rb_erase_rebalance(child, parent, root);
		//调用rb_erase_rebalance来恢复红黑树性质
	}

	return root;
}