上篇博客介绍了怎样删除二分搜索树的最大值和最小值节点,下面介绍怎样删除树的任意一个节点
上篇删除最大值节点的操作,其实删除的节点要么没有左右子节点,要么只可能有左节点,
同样,删除最小值节点的操作,其实删除的节点要么没有左右子节点,要么只可能有右节点
(1)删除只有左节点的节点,如删除节点58,只需要将58删除掉,然后将其左节点50替换其位置即可
(2)删除只有右节点的节点,如删除节点58,只需要将58删除掉,然后将其右节点60替换其位置即可
(3)删除既有左节点又有右节点的节点是最复杂的操作,在1962年,Hibbard提出了一种删除方法,称为 Habbard Deletion,如下图所示,如果需要删除既有左节点又有右节点的节点58(称为d),那么需要找出58的右节点中最小的那个节点s,那么s就是节点59,将节点59放到58的位置即可
具体操作步骤为,首先删除掉s节点,然后将s节点的右节点指向原来d的右节点60,将s的左节点指向原来d的左节点50
最后就可以彻底删除节点58了,将节点59作为新的在该位置的节点
下面是删除节点的程序实现
#include <iostream>
#include <vector>
#include <string>
#include <ctime> //time()函数
#include <queue>
#include <cassert>
#include "FileOps.h"
using namespace std;
template<typename Key, typename Value>
class BST{
private:
struct Node{
Key key;
Value value;
Node *left;
Node *right;
Node(Key key, Value value){
this->key = key;
this->value = value;
this->left = this->right = NULL;
}
Node(Node *node){
this->key = node->key;
this->value = node->value;
this->left = node->left;
this->right = node->right;
}
};
Node *root;
int count;
public:
BST(){
root = NULL;
count = 0;
}
~BST(){
// TODO: ~BST()
destroy(root);
}
int size(){
return count;
}
bool isEmpty(){
return count == 0;
}
void insert(Key key, Value value){
root = insert(root, key, value);
}
bool contain(Key key){
return contain