void Tree_Delete ( NODE **root, NODE *z ) { NODE *y; if (!z->left) { //either z->right is null (no child) //or z->right only (replace z with z->right) printf ("case 1:\n"); Transplant (root, z, z->right); } else if (!z->right) { //z->left only, replace z with z->left printf ("case 2:\n"); Transplant (root, z, z->left); } else { //z->left and z->right are valid, //find successor(z): y = Tree_Successor (z); //y must in the right subtree of z printf ("successor of %d is:\n", z->key); Print_Node (y); // //for debug // if (y) { // printf ("successor: key = %d, p = 0x%x, left = 0x%x, right = 0x%x\n", // y->key, (int)(y->p), (int)(y->left), (int)(y->right)); // if (y->p) { // printf ("p = %d, ", y->p->key); // } // if (y->left) { // printf ("left = %d, ", y->left->key); // } // if (y->right) { // printf ("right = %d, ", y->right->key); // } // printf ("\n"); // } else { // printf ("successor: not found.\n"); // } //and y has no left childs !! if (y->p != z) { printf ("case 3:\n"); //replace y with y->right //update childs manually: //Transplant () updates parents only Transplant (root, y, y->right); y->right = z->right; z->right->p = y; } printf ("case 4:\n"); //if y == z->right, replace z with y directly Transplant (root, z, y); //z has left childs, update their parents y->left = z->left; z->left->p = y; } }
void rb_tree<T>::remove(rb_vertex<T>* out_value) { //out_value is y in Corman // this is y in Corman rb_vertex<T>* successor; // this is x in Corman rb_vertex<T>* child; if (out_value->get_left_child() == 0 or out_value->get_right_child() == 0) { successor = out_value; } else { successor = Tree_Successor(out_value); } if (successor->get_left_child() != 0) { child = successor->get_left_child(); } else { child = successor->get_right_child(); } child->set_parent(successor->get_parent()); if (successor->get_parent() == 0) { root = child; } else { if (successor == successor->get_parent()->get_left_child()) { successor->get_parent()->set_left_child(child); } else { successor->get_parent()->set_right_child(child); } } if (child != out_value) { out_value->set_value(successor->get_value()); } if (successor->get_colour() == BLACK) { remove_fixup(child); } }
pNode RB_Delete(pNode root,pNode t) { pNode DelNode; //{* get tthe node to delete if((t -> left == Nil) || (t -> right == Nil) ) DelNode = t; else DelNode = Tree_Successor(t); //*} pNode PreserveNode; if( DelNode -> left != Nil) PreserveNode = DelNode -> left; else PreserveNode = DelNode -> right; PreserveNode -> parent = DelNode -> parent; // link the DelNode's parent to PreserveNode if( DelNode == Nil ) //if DelNode is the root root = PreserveNode; else { if(DelNode == (DelNode -> parent -> left)) DelNode -> parent -> left = PreserveNode; else DelNode -> parent -> right = PreserveNode; } if(DelNode != t) t -> key = DelNode -> key; /* * if the DelNode's color is black, we must fixup RBT to keep the properties of RBT. * */ if(DelNode -> color == "BLACK") root = RB_Delete_Fixup(root, PreserveNode); return PreserveNode; }
redblack_node * redblack_node::RB_Delete( redblack_node *T, redblack_node* z ) { redblack_node *y, *x, *temp = T; while( temp->parent != NULL ) temp = temp->parent; // point temp to the root of T if( z == NULL ) z = new redblack_node; if( z->left == NULL || z->right == NULL ) y = z; else y = static_cast<redblack_node *>(Tree_Successor( z )); if( y == NULL ) y = new redblack_node(); if( y->left != NULL ) x = y->left; else x = y->right; if( x == NULL ) x = new redblack_node; x->parent = y->parent; if( y->parent == NULL ) temp = x; else if( y == y->parent->left ) y->parent->left = x; else y->parent->right = x; if( y != z ) z->data = strdup( y->data ); if( strcmp( y->color, "BLACK" ) == 0 ) RB_Delete_Fixup( T, x ); return y; }