二叉查找树的删除
二叉查找树删除操作的一大基本原则是要保证删除之后仍是一棵二叉树,
如图所示,为了能保证其仍然为一棵二叉查找树,我们需要在左子树找到比根结点的数据小的最大结点来覆盖根结点,然后删除原来的这一结点(即结点5);另外一种方法是在右子树找到比根结点的数据大的最小结点来覆盖根结点,然后删除原来的这一结点(即结点7)。这两种方法都保证了删除操作后,左子树的每个数据域均小于根结点的数据域,右子树的每个数据域均大于根结点的数据域。因此它仍然是一个二叉查找树。
node* findmax(node* root)//寻找树中的最大权值结点
{
while(root->rchild != NULL)
{
root = root->rchild;
}
return root;
}
node* findmin(node* root)//寻找树中的最小权值结点
{
while(root->lchild != NULL)
{
root = root->lchild;
}
return root;
}
删除操作:
void delete(node* &root, int x)
{
if(root == NULL)//空树,不存在权值为x的结点
{
return ;
}
if(root->data == x)//找到要删除的结点
{
if(root->lchild == NULL && root->rchild == NULL)
{
root == NULL;
}
else if(root->lchild != NULL)//左子树不为空,找比根结点权值小的最大结点
{
node* pre = findmax(root->lchild);
root->data = next->data;//覆盖
delete(root->lchild,pre->data);
}
else if(root->rchild != NULL)//右子树不为空,找比根结点权值大的最小结点
{
node* next = findmin(root->rchild);
root->data = next->data;//覆盖
delete(root->rchild,next->data);
}
}
else if(root->data > x)
{
delete(root->lchild,x);//左子树删除x
}
else
{
delete(root->rchild,x);//右子树删除x
}
}