(1)分3种情况一一讨论:
void tree_delete(pnode &z){
if(z->left == nil && z->right == nil){ //z has no child
if(z == z->p->left)
z->p->left = nil;
else
z->p->right = nil;
}
else if(z->left != nil && z->right != nil){ //z have both 2 children
pnode next = successor(z);
z->key = next->key; //'next' node may have children, can't just delete it
tree_delete(next); //recursively delete the 'next' node
}
else if(z->left != nil){ //z only has the left child
if(z == z->p->left)
z->p->left = z->left;
else
z->p->right = z->left;
z->left->p = z->p;
}
else{ //z only has the right child
if(z == z->p->left)
z->p->left = z->right;
else
z->p->right = z->right;
z->right->p = z->p;
}
}
注意:在z有2个children的情况下,要考虑z的successor有right child的情况,不能直接删除successor节点。递归删除。
(2)非递归删除,分情况讨论,step by step
pnode tree_delete_3(pnode &z){
pnode y,x;
if(z->left == nil || z->right == nil)
y = z; //当z最多有1个child时,将z节点作为待删除节点
else
y = successor(z); //当z有2个children时,将z的successor节点作为待删除节点
if(y->left != nil) //选取待删节点y的非nil child;若y没有child,则x为nil
x = y->left;
else
x = y->right;
if(x != nil) //若x非nil,删除y,将y的p赋给x的p
x->p = y->p;
if(y->p != nil){
if(y == y->p->left)
y->p->left = x;
else
y->p->right = x;
}
if(y != z) //若待删节点y非z节点(即为z的successor情况:successor最多有一个right child,不可能有left child)
z->key = y->key; //则将successor节点的所有数据copy到z节点中,用y代替z被删除
return y; //返回被删除节点y(可省去)
}