二叉搜索树的增删该查操作实现
插入操作:借助辅助递归函数Node* insert(Node *node, Key key, Value value),像根节点为node的二叉搜索树插入一个数据,返回值为根节点,如果node==NULL,那么新建一个节点返回,如果key<node->key, 则插入到左子树,当前返回的根节点为左子数。反之则到右子数
查找操作可以不用递归实现,直接使用while循环,根据大小到左右子树查询,这里的递归比较容易理解,其中查找返回的Value的指针,来处理Value不存在的情况。
遍历操作包括基本的三种DFS遍历,和层序遍历BFS遍历。
删除操作包括删除最小值,删除最大值,删除任意值
最小值一定没有左孩子,所以借助一个辅助的递归函数,Node* removeMin(Node* node),删除以node为根节点的最小值,返回值为当前的根节点,如果node->left==NULL(node为最小值),根节点为node->right,否则递归的到左子树中进行删除,根节点为node->left
最大值一定没有右孩子,同样可以借助一个辅助的递归函数,Node* removeMax(Node* node), 删除以node为根节点的最大值,返回值为当前的根节点,如果node->right==NULL(node为最大值),根节点为node->left,否则递归的到右子数中进行删除,根节点为node->right
删除任意节点操作用同样的递归方式实现,首先通过递归删除找到要删除的节点。如果左儿子为空或者右儿子为空,那么用前面的方法删除就行。如果不是,那么寻找左子数的最大值,或者右子数的最小值,删除右子数的最小值,返回的根节点为拷贝的右子数的最小值,拷贝的右子数的最小值的左耳子为前面节点的左儿子,然后删除要删除的节点。
#include <iostream>
#include <cassert>
#include <queue>
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() {
destory(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 preOrder() {
preOrder(root);
}
void destory() {
destory(root);
}
void levelOrder() {
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* node = q.front();
q.pop();
cout << node->key << endl;
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
}
}
// 寻找最小的键值
Key minimum() {
assert(count != 0);
Node* minNode = minimum(root);
return minNode->key;
}
// 寻找最大的键值
Key maximun() {
assert(count != 0);
Node* maxNode = maximun(root);
return maxNode->key;
}
// 从二叉树删除最小值
void removeMin() {
if (root)
root = removeMin(root);
}
void removeMax() {
if (root)
root = removeMax(root);
}
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 (key == node->key)
return true;
else if (key < node->key)
return contain(node->left, key);
else
return contain(node->right, key);
}
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);
}
void preOrder(Node* node) {
if (node != NULL) {
cout << node->key << endl;
preOrder(node->left);
preOrder(node->right);
}
}
void destory(Node* node) {
if (node != NULL) {
destory(node->left);
destory(node->right);
delete node;
count--;
}
}
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);
}
void remove(Key key) {
remove(root, key);
}
// 删除掉以node为根的二分搜索树中的最小节点
// 返回删除节点后新的二分搜索树的根
Node* removeMin(Node* node) {
if (node->left == NULL) {
Node* rightNode = node ->right;
delete node;
count--;
return rightNode;
}
node->left = removeMin(node->left);
}
// 删除掉以node为根的二分搜索树中的最大节点
// 返回删除节点后新的二分搜索树的根
Node* removeMax(Node* node) {
if (node->right == NULL) {
Node* leftNode = node->left;
delete node;
count--;
return leftNode;
}
node->right = removeMax(node->right);
}
// 删除掉以node为根的二分搜索树中键值为key的节点
// 返回删除节点后新的二分搜索树的根
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 *successor = new Node(minimum(node->right)); //右子树的最小值
count++;
successor->right = removeMin(node->right);
successor->left = node->left;
delete node;
count--;
return successor;
}
}
};