#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>
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 ;
}
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()
{
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;
}