1)我们常用的合并删除,提取的是删除节点的左节点或者是右节点,将其提取到父节点的位置,然后删除父节点,这种情况很可能会使得原来的树结构进行改变,也就是说树的高度发生改变。具体代码如下
template<class T>
void BST<T>::deleteByMerging(BSTNode<T>*& node)
{
BSTNode<T> *tmp=node;
if (node!=0)
{
if (!node->right) node=node->left;
else if (!node->left) node=node->right;
else//将左子树作为根,亦可用右子树作为根
{
tmp=node->left;//先找到左子树
while(tmp->right!=0) tmp=tmp->right;//找到左子树的最后一个右子树,这棵右子树将作为新的节点连接原来node的右子树
tmp->right=node->right;//将左子树最大值节点连接原来右子树的第一个右节点
tmp=node;//删除的是tmp,将node赋值于tmp.
node=node->left;//node节点的指针向下走
}
delete tmp;
}
}
template<class T>
void BST<T>::findAndDeleteByMerging(const T&el)
{
BSTNode<T>*node=root,*prev=0;
while(node!=0)//找到删除节点的前驱
{
if (node->key==el) break;
prev=node;
if(node->key<el) node=node->right;
else node=node->left;
}
if (node!=0&&node->key==el)
{
if (node==root) deleteByMerging(root);//删除合并树
else if(prev->left==node) deleteByMerging(prev->left);
else deleteByMerging(prev->right);
}
else if(root!=0)
{
cout<<"Key"<<el<<"is not in the tree"<<endl;
}
else
cout<<"the tree is empty"<<endl;
}
1)复制删除
赋值删除提取最大的元素赋值于将要删除的node节点,将最大元素的右子树指向被替换的左子树。如此,树的高度影响将会比之前的小
template<class T>
void BST<T>::deleteByCopying(BSTNode<T>*& node)
{
BSTNode<T>*prev,*tmp=node;
if (node->right==0) node=node->left;
else if (node->left==0) node=node->right;
else
{
tmp=node->left;
prev=node;
while(tmp->right!=0)
{
prev=tmp;
tmp=tmp->right;
}
node->key=tmp->key;//将tmp的值赋值于node
if (prev==node)//分两种情况,若是第一个左子树没有右子树,那么直接的连接,将tmp的左子树作为node的左子树
{
prev->left=tmp->left;
}
else prev->right=tmp->left;//若这棵树有右子树,提取最后一个左子树,将其前驱的右子树指向这棵树的左子树
}
delete tmp;
}