二叉查找树 (2)

删除操作要麻烦一点,因为要考虑删掉元素后空的位置需要再新添一个元素,不然,如果删除的不是叶子节点的话树结构就被破坏了。remove函数用来删除二叉查找树中指定的元素值。在删除子节点时,需要分以下几种情况进行考虑:

需要删除的子节点,它没有任何子节点;例如图中的节点9、节点17、节点21、节点56和节点88;这些节点它们都没有子节点;

需要删除的子节点,只有一个子节点(只有左子节点或右子节点);例如图中的节点16和节点40;这些节点它们都只有一个子节点;

需要删除的子节点,同时拥有两个子节点;例如图中的节点66等。

这里写图片描述

复制删除

首先介绍的是复制删除的思路,即从树中另选择一个节点代替被删除节点的值,再将被选择的那个节点删除。具体如下:

对于情况1,直接删除对应的节点即可;实现起来时比较简单的;

对于情况2,直接删除对应的节点,然后用其子节点占据删除掉的位置;

对于情况3,是比较复杂的。有2种方法,选择哪一种方法都可以:

其一,(选择右子树中最小值节点)首先在需要被删除节点的右子树中找到最小值节点,然后使用该最小值替换需要删除节点的值,然后在右子树中删除该最小值节点。

其二,(选择左子树中最大值节点)在需要被删除节点的左子树中找到最大值节点,然后使用该最大值替换需要删除节点的值,然后在左子树中删除该最大值节点。

template<class T> void BST<T>::deleteByCopying(BSTNode<T>*& node) { BSTNode<T> *previous, *tmp = node; if (node->right == 0) // node has no right child; node = node->left; else if (node->left == 0) // node has no left child; node = node->right; else { tmp = node->left // node has both children; previous = node; // 1. 这里采用的是选择选择左子树中的最大值节点的方法 while (tmp->right != 0) { // 2. 找左子树中的最大值节点 previous = tmp; tmp = tmp->right; } node->el = tmp->el; // 3.将左子树中的最大值节点的值赋值给被删除节点的元素值 // 处理删除被选择的节点 if (previous == node) // 如果左子树最大值节点的父节点为被删除节点的话,将被选择的节点(左子树最大值节点)左子树上移 previous->left = tmp->left; else previous->right = tmp->left; // 4. 如果左子树最大值节点的父节点不是被删除节点的话,将被选择的节点(左子树最大值节点)的左子树的父节点设置为被选择节点的前驱节点的右子节点 } delete tmp; // 5. } 上面的代码不好理解的话,下面这段代码会好理解一下,也可以看下面这段代码,作用是一样的。
```c++
// 这里采用的方法一,选择右子树中最小值节点
template
void BST::remove(const T& x, Node* &t) const {
if(NULL == t)
return;
// 移除一个节点稍微麻烦一点,因为移除一个节点后二叉树需要将移除的位置再填一个节点过去
if(x < t->data) {
remove(x, t->left);
} else if(x > t->data) {
remove(x, t->right);
} else if(t->left != NULL && t->right != NULL) {
//拥有2个子节点
t->data = findMin(t->right)->data; //当前元素用右子树最小值填充
remove(t->data, t->right); //填充值被移走了,需要删除原填充值
} else if(t->left == NULL && t->right == NULL) {
//没有子节点,最简单的情况,直接删掉
delete t;
t = NULL;
} else if(t->left == NULL || t->right == NULL) {
//拥有一个子节点
Node* p = t;
t = (t->left != NULL)?t->left:t->right;//用其子节点占据删除掉的位置;
delete p;//直接删除对应的节点
}
}

//删除指定元素
template
void BST::remove(const T& x) {
remove(x, root);
}
```

合并删除

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzfxj.html