删除一棵平衡二叉树中的节点,有两种方法
第一种方法:
a.如果被删除的节点p没有左子树,则用p的右孩子代替p即可
b.否则,在p的左子树中找到关键字最大的节点r,将r的右指针指向p的右孩子,用p的左孩子代替p即可
//节点删除 方法1
bool CBTree::NodeDelete(node *&Node,int Data)
{
node *p,*q;
if(num==0||Node==NULL)
{
return false;
}
if(num==1)
{
delete Node;
Node=NULL;
num--;
return true;
}
if(Node->data==Data)
{
if(Node->left)
{
p=Node->left;
while(p->right)
{
p=p->right; //左孩子中的最大节点
}
p->right=Node->right;
q=Node->left;
*Node=*Node->left;
}
else
{
q=Node->right;
*Node=*Node->right;
}
delete q;
num--;
return true;
}
else if(Node->data>Data)
{
if(!Node->left->left&&!Node->left->right) //叶子节点
{
if(Node->left->data==Data)
{
delete Node->left;
num--;
(*Node).left=NULL;
return true;
}
}
return NodeDelete(Node->left,Data);
}
else
{
if(!Node->right->left&&!Node->right->right) //叶子节点
{
if(Node->right->data==Data)
{
delete Node->right;
num--;
(*Node).right=NULL;
return true;
}
}
return NodeDelete(Node->right,Data);
}
}
第二种方法:
a.如果被删除的节点p没有左子树,则用p的右孩子代替p即可
b.否则,在p的左子树中找到关键字最大的节点r,用r节点代替被删除的节点p,p原来的左右孩子不变,并且用原来r节点的孩子代替原来的r节点。
//节点删除 方法2
bool CBTree::DeleteNode(node *&Node,int Data)
{
node *p,*q;
if(num==0||Node==NULL)
{
return false;
}
if(num==1)
{
delete Node;
Node=NULL;
num--;
return true;
}
if(Node->data==Data)
{
q=Node;
if(Node->left)
{
p=Node->left;
while(p->right)
{
q=p;p=p->right; //左孩子中的最大节点
}
Node->data=p->data;
if(p->left)
{
q=p->left;*p=*p->left;
delete q;
}
else
{
if(q==Node) //最大节点是左节点
q->left=NULL;
else
q->right=NULL;
delete p;
}
}
else
{
p=Node->right;
*Node=*Node->right;
delete p;
}
num--;
return true;
}
else if(Node->data>Data)
{
if(!Node->left->left&&!Node->left->right) //叶子节点
{
if(Node->left->data==Data)
{
delete Node->left;
num--;
(*Node).left=NULL;
return true;
}
}
return DeleteNode(Node->left,Data);
}
else
{
if(!Node->right->left&&!Node->right->right) //叶子节点
{
if(Node->right->data==Data)
{
delete Node->right;
num--;
(*Node).right=NULL;
return true;
}
}
return DeleteNode(Node->right,Data);
}
}
二叉排序树性能分析:
当二叉排序树是完全二叉树时,其平均查找性能最佳为log2n,与有序表的折半查找性能相同。
当二叉排序树退化为一棵单支树时,二叉排序树的平均查找性能最差为(n+1)/2,与顺序表的平均查找长度相同。