#include <iostream>
#include <queue>
#include <cassert>
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)
{
key=key;
value=value;
left=nullptr;
right=nullptr;
}
Node(Node* node)
{
key=node->key;
value=node->value;
left=node->left;
right=node->right;
}
};
Node* root; //BST的根
int cnt; //BST中节点的个数
public:
BST() //构造函数
{
root=nullptr;
cnt=0;
}
~BST() //析构函数
{
__destory(root);
}
int sz()
{
return cnt;
}
bool isEmpty()
{
return cnt==0;
}
//向二叉搜索树种插入元素
void myInsert(Key key,Value value)
{
root=__insert(root,key,value);
}
//判断二叉搜索树种是否包含某个元素
bool myContain(Key key)
{
return __myContain(root,key);
}
Value* mySearch(Key key)
{
return __mySearch(root,key);
}
//前序遍历
void preOrder()
{
__preOrder(root);
}
//中序遍历
void inOrder()
{
__inOrder(root);
}
//层序遍历
void levelOrder()
{
if(node==nullptr)
return;
queue<Node*> qu;
qu.push(root);
while(!qu.empty())
{
Node* node=qu.front();
qu.pop();
cout<<node->key<<endl;
if(node->left)
qu.push(node->left);
if(node->right)
qu.push(node->right);
}
}
//寻找最小的键
Key minimum()
{
assert(cnt>0);
Node* node= __minimum(root);
return node->key;
}
//寻找最大的键
Key minimum()
{
assert(cnt>0);
Node* node= __maximum(root);
return node->key;
}
//从二叉搜索树种删除最小值所在的节点
void removeMin()
{
if(root)
{
root=__removeMin(root);
}
}
//从二叉搜索树种删除最大值所在的节点
void removeMax()
{
if(root)
{
root=__removeMax(root);
}
}
//二叉树中删除键值为key的节点
void myRemove(Key key)
{
root=__myRemove(root,key);
}
private:
//向以node为根的二叉搜索树中,插入节点(key,value)
//返回插入新节点后的二叉搜索树的根
Node* __insert(Node* node,Key key,Value value)
{
if(node==nullptr) //根节点为空,直接生成一个节点并返回
{
cnt++;
return new Node(key,value);
}
if(key==node->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;
}
//判断以node为根的二叉搜索树中是否存在node
bool __myContain(Node* node,Key key)
{
if(node==nullptr)
return false;
if(node->key==key)
{
return true;
}
else if(key<node->key)
{
return __myContain(node->left,key);
}
else
{
return __myContain(node->right,key);
}
}
//在以node为根的二叉搜索树中查找key
Value* __mySearch(Node* node,Key key)
{
if(node==nullptr)
{
return nullptr;
}
if(node->key==key)
{
return &(node->value);
}
else if(key < node->key)
{
return __myContain(node->left,key);
}
else
{
return __myContain(node->right,key);
}
}
void __preOrder(Node* node)
{
if(node==nullptr)
{
return;
}
cout<<node->key<<endl;
__preOrder(node->left);
__preOrder(node->right);
}
void __inOrder(Node* node)
{
if(node==nullptr)
{
return;
}
__inOrder(node->left);
cout<<node->key<<endl;
__inOrder(node->right);
}
void __destory(Node* node)
{
if(node==nullptr)
{
return;
}
__destory(node->left);
__destory(node->right);
delete node;
cnt--;
}
Node* __minimum(Node* node)
{
if(node->left==nullptr)
{
return node;
}
return __minimum(node->left);
}
Node* __maximum(Node* node)
{
if(node->right==nullptr)
{
return node;
}
return __maximum(node->right);
}
//删除掉以node为根的二分搜索树中的最小节点
//返回删除节点后新的二分搜索树的根
Node* __removeMin(Node* node)
{
if(node->left==nullptr)
{
Node* rightNode=node->right;
delete node;
cnt--;
return rightNode;
}
node->left=__removeMin(node->left);
return node;
}
//删除掉以node为根的二分搜索树中的最大节点
//返回删除节点后新的二分搜索树的根
Node* __removeMax(Node* node)
{
if(node->right==nullptr)
{
Node* leftNode=node->left;
delete node;
cnt--;
return leftNode;
}
node->right=__removeMax(node->right);
return node;
}
//删除掉以node为根的二分搜索树中键值为key的节点
//返回删除节点后新的二分搜索树的根
Node* __myRemove(Node* node,Key key)
{
if(node==nullptr)
{
return nullptr;
}
if(key<node->key)
{
node->left=__myRemove(node->left,key);
return node;
}
else if(key>node->key)
{
node->right=__myRemove(node->right,key);
return node;
}
else //要删除当前节点,首先判断左右孩子是否有是空的
{
if(node->left==nullptr)
{
Node* rightnode=node->right;
delete node;
cnt--;
return rightnode;
}
if(node->right==nullptr)
{
Node* leftnode=node->left;
delete node;
cnt--;
return leftnode;
}
//左右子树都不为空
//找到node右子树的最小值,替换node
Node* successor=new Node(minimum(node->right)); //复制该节点
cnt++;
//左孩子是原来节点的左孩子
successor->left=node->left;
//右孩子是删除掉最小节点后返回的根节点
successor->right=removeMin(node->right);
delete node;
cnt--;
return successor;
}
}
};