#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include <cmath>
#include <cassert>
#include <queue>
using namespace std;
template <typename Key,typename Value>
class BST{
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);
}
Value* Search(Key key){
return Search(root,key);
}
//前序遍历
void preOrder(){
preOrder(root);
}
//中序遍历
void inOrder(){
inOrder(root);
}
//后序遍历
void postOrder(){
postOrder(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 maximum(){
assert(Count!=0);
Node* maxNode=maximum(root);
return maxNode->key;
}
//从二叉树中删除最小值所在的节点
void removeMin(){
if(root)
root=removeMin(root);
}
//从二叉树中删除最大值所在的节点
void removeMax(){
if(root)
root=removeMax(root);
}
//从二叉树中删除键值为key的节点
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->key=key;
else if(key<node->key)
node->left=Insert(node->left,key,value);
else
node->right=Insert(node->right,key,value);
return node;
}
//查找以node为根的二分搜索树中是否包含键值为key的节点
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);
}
//在以node为根的二分搜索树中查找key所对应的value
Value* Search(Node *node,Key key){
if(node==NULL)
return NULL;
if(key==node->value)
return &(node->value);
else if(key<node->key)
return Search(node->left,key);
else
return Search(node->right,key);
}
//对以node为根的二分搜索树进行前序遍历
void preOrder(Node *node){
if(node !=NULL){
cout<<node->key<<endl;
preOrder(node->left);
preOrder(node->right);
}
}
//对以node为根的二分搜索树进行中序遍历
void inOrder(Node *node){
if(node!=NULL){
inOrder(node->left);
cout<<node->key<<endl;
inOrder(node->right);
}
}
//对以node为根的二分搜索树进行后序遍历
void postOrder(Node *node){
if(node!=NULL){
postOrder(node->left);
postOrder(node->right);
cout<<node->key<<endl;
}
}
//用类似后序遍历的方法释放空间
void destory(Node *node){
if(node !=NULL){
destory(node->left);
destory(node->right);
delete(node);
Count--;
}
}
//在以node为根的二分搜索树中,返回最小键值的节点
Node* minimum(Node* node){
if(node->left == NULL)
return node;
return minimum(node->left);
}
//在以node为根的二分搜索树中,返回最大键值的节点
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为根的二分搜索树中的最大节点
//返回删除节点后新的二分搜索树的根
Node* removeMax(Node* node){
if(node->right==NULL){
Node* leftNode=node->left;
delete node;
Count--;
return leftNode;
}
node->right=removeMax(node->right);
return node;
}
//删除掉以node为根的二分搜索树中键值为key的节点
//返回删除节点后新的二分搜索树的根O(logn)
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));
Count++;
successor->right=removeMin(node->right);
successor->left=node->left;
delete node;
Count--;
return successor;
}
}
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;//记录节点数
};
二分搜索树常见操作(C++版)
最新推荐文章于 2020-06-17 16:31:47 发布