BST首先是二叉树,对应的二叉树定义和常用操作封装在以下头文件"bintree.h"
// 二叉树的头文件
#ifndef bintree_h
#define bintree_h
#include <iostream>
using namespace std;
template<class Elem>
struct BinNode{
Elem data;
BinNode<Elem>* left;
BinNode<Elem>* right;
BinNode(Elem x){
data=x;
left=right=NULL;
}
};
template<class Elem>
class BinTree{
protected:
BinNode<Elem>* root;
void rpreprint(BinNode<Elem>* r);
void rinprint(BinNode<Elem>* r);
void rpostprint(BinNode<Elem>* r);
int cntLeaves(BinNode<Elem>* r);
BinNode<Elem>* rfindX(Elem x,BinNode<Elem>* r);
void rprint(BinNode<Elem>* r,int depth);
public:
BinTree() {root=NULL;}
BinTree(Elem r){
root=new BinNode<Elem>(r);
}
~BinTree(){ };
void preprint(){
rpreprint(root);
cout<<endl;
}
void inprint(){
rinprint(root);
}
void postprint(){
rpostprint(root);
}
void print(){
rprint(root,0);
}
BinNode<Elem>* findX(Elem x){
return rfindX(x,root);
}
bool insert(Elem p,int LorR,Elem x);
int cnt(){
return cntLeaves(root);
}
};
template<class Elem>
void BinTree<Elem>::rpreprint(BinNode<Elem>* r){ // 对于传指针,一定不要掉以轻心,要首先看一下指针是不是空指针
if(r==NULL) return;
cout<<r->data<<" ";
rpreprint(r->left);
rpreprint(r->right);
}
template<class Elem>
void BinTree<Elem>::rinprint(BinNode<Elem>* r){
if(r==NULL) return;
rinprint(r->left);
cout<<r->data<<" ";
rinprint(r->right);
}
template<class Elem>
void BinTree<Elem>::rpostprint(BinNode<Elem>* r){
if(r==NULL) return;
rinprint(r->left);
rinprint(r->right);
cout<<r->data<<" ";
}
template<class Elem>
int BinTree<Elem>::cntLeaves(BinNode<Elem>* r){
if(r==NULL) return 0;
if(r->left==NULL && r->right==NULL) return 1;
return cntLeaves(r->left)+cntLeaves(r->right);
}
template<class Elem>
BinNode<Elem>* BinTree<Elem>::rfindX(Elem x,BinNode<Elem>* r){
if(!r) return NULL;
if(r->data==x) return r;
BinNode<Elem>* found;
found=rfindX(x,r->left);
return found?found:rfindX(x,r->right);
}
template<class Elem>
void BinTree<Elem>::rprint(BinNode<Elem>* r,int depth){
for(int i=0;i<depth;i++) cout<<" ";
if(!r){
cout<<"[/]"<<endl;
}
else{
cout<<r->data<<endl;
rprint(r->left,depth+1);
rprint(r->right,depth+1);
}
}
template<class Elem>
bool BinTree<Elem>::insert(Elem p,int LorR,Elem x){
BinNode<Elem>* found;
found=findX(p);
if(!found) return false;
if(LorR==0){
if(found->left) return false;
found->left=new BinNode<Elem>(x);
}
else{
if(found->right) return false;
found->right=new BinNode<Elem>(x);
}
return true;
}
#endif // bintree_h
二叉搜索树的实现
// 二叉搜索树
#include <iostream>
#include "bintree.h"
using namespace std;
template<class Elem>
class BSTree : public BinTree<Elem>{
protected:
BinNode<Elem>* rfindMax(BinNode<Elem>* r){
if(r->right==NULL) return r;
return rfindMax(r->right); // 尾递归
}
BinNode<Elem>* rinsert(Elem x,BinNode<Elem>* r){
if(r==NULL){
r=new BinNode<Elem>(x);
if(!r) throw -1;
}
else if(x<r->data) r->left=rinsert(x,r->left);
else if(x>r->data) r->right=rinsert(x,r->right);
else throw -2;
return r;
}
BinNode<Elem>* remove(Elem x,BinNode<Elem>* r){
BinNode<Elem>* tmp;
if(!r) throw -1;
else if(x<r->data){
r->left=remove(x,r->left);
}
else if(x>r->data){
r->right=remove(x,r->right);
}
else{
if(r->left && r->right){
tmp=rfindMax(r->left);
r->data=tmp->data;
r->left=remove(tmp->data,r->left);
}
else{
tmp=r;
r=r->left?r->left:r->right;
delete tmp;
}
}
return r;
}
public:
BSTree(){
this->root=NULL;
}
BinNode<Elem>* findMax(){
// return rfindMax(this->root);
BinNode<Elem>* tmp=this->root;
while(tmp && tmp->right){
tmp=tmp->right;
}
return tmp;
}
BinNode<Elem>* findMin(){
BinNode<Elem>* tmp=this->root;
while(tmp && tmp->left){
tmp=tmp->left;
}
return tmp;
}
BinNode<Elem>* findX(Elem x){
BinNode<Elem>* tmp=this->root;
while(tmp && x!=tmp->data){
if(x<tmp->data) tmp=tmp->left;
else tmp=tmp->right;
}
return tmp;
}
bool insert(Elem x){
try{
this->root=rinsert(x,this->root);
}
catch(int e){
return false;
}
return true;
}
bool remove(Elem x){
try{
this->root=remove(x,this->root);
}
catch(int e){
return false;
}
return true;
}
};
int main(){
BSTree<int> bt;
bt.insert(10);
bt.insert(5);
bt.insert(20);
bt.insert(8);
bt.insert(15);
bt.insert(2);
bt.insert(6);
bt.print();
cout<<"---------"<<endl;
bt.remove(10);
bt.print();
return 0;
}