数据结构:二叉查找树(BST)

#include <iostream>
#include <iomanip>
#include <queue>
#ifndef BST_HPP
#define BST_HPP

//二叉树结点定义
template<typename DataType>
class BinNode{
public:
    DataType data;
    BinNode *left;
    BinNode *right;
    BinNode():left(0),right(0){}
    BinNode(DataType item):data(item),left(0),right(0){}
};

template<typename DataType>
class BST{
public:
    BST();//无参构造
    bool empty() const; //判空
    void inOrder(ostream & out) const; //中序遍历
    void preOrder(ostream& out) const;//前序遍历
    void postOrder(ostream& out) const;//后序遍历
    void levelOrder(ostream& out) const;//层次遍历
    void graph(ostream& out) const;//树形输出

    bool search(const DataType& item) const;//查找
    void insert(const DataType& item);//插入
    void remove(const DataType& item);//删除

private:
    //辅助函数系列
    //中序遍历辅助
    void inOrderAux(ostream& out,BinNode<DataType>* subtreePtr) const;
    //前序遍历辅助
    void preOrderAux(ostream& out,BinNode<DataType>* subtreePtr) const;
    //后序遍历辅助
    void postOrderAux(ostream& out,BinNode<DataType>* subtreePtr) const;
    //层次遍历辅助
    void levelOrderAux(ostream& out,BinNode<DataType>* subtreePtr) const;
    //图形输出辅助
    void graphAux(ostream& out,int indent,BinNode<DataType>* subtreeRoot) const;
    //用于删除的查找
    void search2(const DataType& item,bool& found,BinNode<DataType>* & locptr,BinNode<DataType>* & parent) const;

    BinNode<DataType>* myRoot;//树根
};

template<typename DataType>
inline BST<DataType>::BST():myRoot(0) {}

template<typename DataType>
inline bool BST<DataType>::empty() const {return myRoot==0; }

template<typename DataType>
inline void BST<DataType>::inOrder(ostream& out) const
{  inOrderAux(out,myRoot);  }

template<typename DataType>
void BST<DataType>::inOrderAux(ostream& out,BinNode<DataType>* subtreeRoot) const
{
    if(subtreeRoot!=0)
    {
        inOrderAux(out,subtreeRoot->left);
        out<<subtreeRoot->data<<" ";
        inOrderAux(out,subtreeRoot->right);
    }
}

template<typename DataType>
inline void BST<DataType>::preOrder(ostream& out) const
{  preOrderAux(out,myRoot);  }

template<typename DataType>
void BST<DataType>::preOrderAux(ostream& out,BinNode<DataType>* subtreeRoot) const
{
    if(subtreeRoot!=0)
    {
        out<<subtreeRoot->data<<" ";
        preOrderAux(out,subtreeRoot->left);
        preOrderAux(out,subtreeRoot->right);
    }
}

template<typename DataType>
inline void BST<DataType>::postOrder(ostream& out) const
{  postOrderAux(out,myRoot);  }

template<typename DataType>
void BST<DataType>::postOrderAux(ostream& out,BinNode<DataType>* subtreeRoot) const
{
    if(subtreeRoot!=0)
    {
        postOrderAux(out,subtreeRoot->left);
        postOrderAux(out,subtreeRoot->right);
        out<<subtreeRoot->data<<" ";
    }
}

template<typename DataType>
inline void BST<DataType>::levelOrder(ostream& out) const
{  levelOrderAux(out,myRoot);  }

template<typename DataType>
void BST<DataType>::levelOrderAux(ostream& out,BinNode<DataType>* subtreeRoot) const
{
    queue<BinNode<DataType>*> q;
    q.push(subtreeRoot);
    while(!q.empty())
    {
        BinNode<DataType>* front = q.front();
        out<<front->data<<" ";
        q.pop();
        if(front->left != 0)
            q.push(front->left);
        if(front->right != 0)
            q.push(front->right);
    }
}

template<typename DataType>
inline void BST<DataType>::graph(ostream& out) const
{ graphAux(out,0,myRoot);}

template<typename DataType>
void BST<DataType>::graphAux(ostream& out,int indent,BinNode<DataType>* subtreeRoot) const
{
    if(subtreeRoot!=0)
    {
        graphAux(out,indent+8,subtreeRoot->right);
        out<<setw(indent)<<" "<<subtreeRoot->data<<endl;
        graphAux(out,indent+8,subtreeRoot->left);
    }
}


/* 递归版本
 template<typename DataType>
 inline bool BST<DataType>::search(const DataType& item) const
 { return searchAux(myRoot,item);}

 template<typename DataType>
 bool BST<DataType>::searchAux(BST<DataType>::BinNodePointer subtreeRoot,const DataType& item) const
 {
    if(subtreeRoot==0) return false;
    if(item<subtreeRoot->data) return searchAux(subtreeRoot->left,item);
    else if(subtreeRoot0->data<item) return searchAux(subtreeRoot->right,item);
    else return true;
 }
 */

template<typename DataType>
bool BST<DataType>::search(const DataType& item) const
{
    BinNode<DataType>* locptr=myRoot;
    bool found=false;
    while(!found&&locptr!=0)
    {
        if(item<locptr->data) locptr=locptr->left;
        else if(locptr->data<item) locptr=locptr->right;
        else found =true;
    }
    return found;
}

template<typename DataType>
void BST<DataType>::insert(const DataType& item)
{
    BinNode<DataType>* locptr=myRoot,*parent=0;
    bool found=false;
    while(!found&&locptr!=0)
    {
        parent=locptr;
        if(item<locptr->data) locptr=locptr->left;
        else if(locptr->data<item) locptr=locptr->right;
        else found=true;
    }
    if(!found){
        locptr=new BinNode<DataType>(item);
        if (parent==0) myRoot=locptr;
        else if(item<parent->data) parent->left=locptr;
        else parent->right=locptr;
    }
    else
        cout<<"Item already in the tree!"<<endl;
}

template<typename DataType>
void BST<DataType>::remove(const DataType& item)
{
    bool found;
    BinNode<DataType>* x,*parent;
    search2(item,found,x,parent);

    if(!found){
        cout<<"Item not in the BST"<<endl;
        return ;
    }
    //else
    if(x->left!=0 && x->right!=0)
    {
        BinNode<DataType>* xSucc=x->right;
        parent=x;
        while(xSucc->left!=0){
            parent=xSucc;
            xSucc=xSucc->left;
        }
        x->data=xSucc->data;
        x=xSucc;
    }
        BinNode<DataType>* subtree=x->left;
        if(subtree==0) subtree=x->right;
        if(parent==0) myRoot=subtree;
        else if(parent->left==x) parent->left=subtree;
        else parent->right=subtree;
        delete x;
}

template<typename DataType>
void BST<DataType>::search2(const DataType & item,bool& found,BinNode<DataType>* & locptr,
                            BinNode<DataType>* & parent) const
{
    locptr=myRoot;
    parent=0;
    found=false;
    while(!found&&locptr!=0)
    {
        if(item<locptr->data){
            parent=locptr;
            locptr=locptr->left;
        }
        else if(locptr->data<item){
            parent=locptr;
            locptr=locptr->right;
        }
        else
            found=true;
    }
}

#endif
#include <iostream>
using namespace std;
#include "BST.hpp"

int main()
{
    //测试构造函数和empty()
    BST<int> intBST;
    cout<<"构造空BST"<<endl;
    cout<<"BST "<<(intBST.empty()?"是":"不是")<<"空树"<<endl;

    //测试中序遍历
    cout<<"中序(inOrder)遍历:"<<endl;
    intBST.inOrder(cout);

    //测试插入操作
    cout<<"现在开始插入(insert)测试:"<<endl;
    int number;
    for(;;){
        cout<<"插入值(-999结束)";
        cin>>number;
        if(number==-999) break;
        intBST.insert(number);
    }
    intBST.graph(cout);

    //测试前序遍历
    cout<<"前序(preOrder)遍历:"<<endl;
    intBST.preOrder(cout);
    cout<<endl;

    //测试后序遍历
    cout<<"后序(postOrder)遍历:"<<endl;
    intBST.postOrder(cout);
    cout<<endl;
    //测试层次遍历
    cout<<"层次(level)遍历:"<<endl;
    intBST.levelOrder(cout);
    cout<<endl;
    //测试查找
    cout<<"现在开始查找(search)测试:"<<endl;
    for(;;){
        cout<<"查找值(-999结束)";
        cin>>number;
        if(number==-999) break;
        cout<<(intBST.search(number)?"找到":"找不到")<<endl;
    }

    //测试删除
    cout<<"现在开始删除(remove)测试:"<<endl;
    for(;;){
        cout<<"删除值(-999结束)";
        cin>>number;
        if(number==-999) break;
        intBST.remove(number);
        intBST.graph(cout);
    }

    return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_41579622/article/details/81632279