二叉搜索树中最复杂的操作:删除一个节点
1.删除二叉搜索树中的最小节点:一直向左子树遍历,直到遍历到某个节点的左子树为空时,说明该节点就是整个二叉搜索树的最小节点。如果该节点还有右子树,直接把右子树放到应被删除的节点上就可以了。
2.删除二叉搜索树中的最大节点:一直向右子树遍历,直到遍历到某个节点的右子树为空时,说明该节点就是整个二叉搜索树的最大节点。如果该节点还有左子树,直接把左子树放到应被删除的节点上就可以了。
3.如果要删除的节点只有一个孩子,或左子树或右子树,那么操作都是简单的,和上面类似。
4.删除任意节点(既有左孩子又有右孩子):用该节点右子树中的最小节点(也就是该节点的后继节点)替换要删除的节点即可。为什么?因为该节点的右子树中任意节点都一定是比左子树大的,同时又为了满足二叉搜索树右子树的节点大于当前结点的性质,选取要删除节点右子树中的最小节点替换该节点即可。
当然,使用前驱节点(左子树中的最大节点)代替要删除的节点也是可以的!
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 *root;
int count;
public:
BST()
{
root = NULL;
count = 0;
}
~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(root, key);
}
Value* search(Key key)
{
return search(root, key);
}
void destroy(Node* node)
{
if (node != NULL)
{
destroy(node->left);
destroy(node->right);
delete node;
count--;
}
}
Key minimum()
{
assert(count != 0);
Node* minNode = minimum(root);
return minNode->key;
}
Key maximum()
{
assert(count != 0);
Node* maxNode = maximum(root);
return maxNode->key;
}
void removeMin()
{
if (root)
root = removeMin(root);
}
void remove(Key key)
{
root = remove(root, key);
}
private:
//向node为根的二叉搜索树中插入(key,value),返回插入新节点后的二叉搜索树的根
Node* insert(Node *node, Key key, Value value)
{
if (node == NULL)
{
count++;
return new Node(key, value);
}
if (key == node->key)
node->value = value;
else if (key < node->key)
node->left = insert(node->left, key, value);
else
node->right = insert(node->right, key, value);
return node;
}
bool contain(Node* node, Key key)
{
if (node == NULL)
return false;
if (node->key == key)
return true;
else if (key < node->key)
return contain(node->left, key);
else
return contain(node->right, key);
}
//在以node为根的二叉搜索树中查找key所对应的value
Value* search(Node* node, Key key)
{
if (node == NULL)
return NULL;
if (key == node->key)
return &(node->value);
else if (key < node->key)
return search(node->left, key);
else
return search(node->right, key);
}
Node* minimum(Node* node)
{
if (node->left == NULL)
return node;
return minimum(node->left);
}
Node* maximum(Node* node)
{
if (node->right == NULL)
return node;
return maximum(node->right);
}
//删掉以node为根的二分搜索树中的最小节点,返回删除后新的二分搜索树的根
Node* removeMin(Node* node)
{
if (node->left == NULL)
{
Node* rightNode = node->right;
delete node;
count--;
return rightNode;
}
node->left = removeMin(node->left);
return node;
}
Node* remove(Node* node, Key key)
{
if (node == NULL)
return NULL;
if (key < node->key)
{
node->left = remove(node->left, key);
return node;
}
else if (key > node->key)
{
node->right = remove(node->right, key);
return node;
}
else//key == node->key
{
if (node->left == NULL)
{
Node* rightNode = node->right;
delete node;
count--;
return rightNode;
}
if (node->right == NULL)
{
Node* leftNode = node->left;
delete node;
count--;
return leftNode;
}
//node->left!=NULL && node->right!=NULL
Node *successor = new Node(minimum(node->right));
successor->left = removeMin(node->right);
successor->left = node->left;
delete node;
count--;
return successor;
}
}
};