BST的C++實現

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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章