用类模版实现BST搜索二叉树,简单但不容易,其中的remove代码写的很好,讲四种情况集合在一起,代码精简,但不易看懂
头文件
#include<iostream>//new const inline 构造函数
#include <new>
#include <iomanip>
#ifndef BINARY_SEACH_TREE
#define BINARY_SEACH_TREE
template <typename DataType>
class BST
{
public:
//函数成员//
BST();
bool empty() const;
bool search(const DataType & item) const;
void insert(const DataType & item);
void remove(const DataType & item);
void inorder(ostream & out) const;
void graph(ostream &out) const;
private:
//节点类//
class BinNode
{
public:
DataType data;
BinNode * left;
BinNode * right;
BinNode():left(0),right(0){}
BinNode(DataType item):data(item),left(0),right(0){}
};
typedef BinNode * BinNodePointer;
//私有函数成员//
void search2(const DataType & item,bool&found,BinNodePointer&locptr,BinNodePointer&parent)const;
void inorderAux(ostream & out,BinNodePointer subtreePtr) const;
void graphAux(ostream & out,int indent,BinNodePointer subtreeRoot) const;
//数据成员//
BinNodePointer myRoot;
};
//类模版声明结束
//--构造函数的定义--
template<typename DataType>
inline BST<DataType>::BST(): myRoot(){}
//--empty()的定义--
template<typename DataType>
inline bool BST<DataType>::empty()const
{return myRoot==0;}
//--search()的定义
template<typename DataType>
bool BST<DataType>::search(const DataType&item)const
{
BST<DataType>::BinNodePointer Locptr=myRoot;
bool found =false;
while(!found&&Locptr!=0)
{
if(item<Locptr->data)
Locptr=Locptr->left;
else if(item>Locptr->data)
Locptr=Locptr->right;
else
found=true;
}
return found;
}
//--insert()的定义--
template<typename DataType>
void BST<DataType>::insert(const DataType&item)
{
BST<DataType>::BinNodePointer locptr=myRoot,
parent=0;
bool found =false;
while(!found&&locptr!=0)
{
parent=locptr;
if(item<locptr->data)
locptr=locptr->left;
else if(item>locptr->data)
locptr=locptr->right;
else
found =true;
}
if(!found)
{
locptr=new BST<DataType>::BinNode(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\n";
}
//--remove()的定义--
template<typename DataType>
void BST<DataType>::remove(const DataType&item)
{
bool found;
BST<DataType>::BinNodePointer x,parent;
search2(item,found,x,parent);
if(!found)
{
cout<<"Item not in the BST\n";
return;
}
//else
if (x->left!=0&&x->right!=0)//两子树都不空的情况,选取次小的节点代替待删除的节点
{
BST<DataType>::BinNodePointer xSucc=x->right;
parent=x;
while(xSucc->left!=0)
{
parent=xSucc;
xSucc=xSucc->left;
}
x->data=xSucc->data;
x=xSucc;
}
BST<DataType>::BinNodePointer 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;
}
//--inoeder()的定义--
template<typename DataType>
void BST<DataType>::inorder(ostream&out)const
{
inorderAux(out,myRoot);
}
//--graph()的定义--
template<typename DataType>
inline void BST<DataType>::graph(ostream&out)const
{
graphAux(out,0,myRoot);
}
//--search2()的定义--
template<class DataType>
void BST<DataType>::search2(const DataType & item,bool&found,
BinNodePointer & locptr,
BinNodePointer & 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;
}
}
//--inorderAux()的定义--
template<typename DataType>
void BST<DataType>::inorderAux(ostream&out,
BinNodePointer subtreeRoot)const
{
if (subtreeRoot!=0)
{
inorderAux(out,subtreeRoot->left);
out<<subtreeRoot->data<<" ";
inorderAux(out,subtreeRoot->right);
}
}
//-graphAux()的定义--
template<typename DataType>
void BST<DataType>::graphAux(ostream&out,int indent,
BinNodePointer subtreeRoot) const
{
if (subtreeRoot!=0)
{
graphAux(out,indent+8,subtreeRoot->right);
out<<setw(indent)<<" "<<subtreeRoot->data<<endl;
graphAux(out,indent+8,subtreeRoot->left);
}
}
#endif
Cpp文件
#include<iostream>
using namespace std;
#include "BST.h"
int main()
{
BST<int>intBST;
cout<<"BST "<<(intBST.empty()?"is":"is not")<<" empty\n";
intBST.inorder(cout);
int number;
cout<<"Item to insert(-999 to stop):";
for(;;)
{
cin>>number;
if (number==-999)break;
intBST.insert(number);
}
intBST.graph(cout);
cout<<"BST"<<(intBST.empty()?"is":"is not")<<"empty\n"<<endl;
cout<<"Inorder Traversal of BST:\n";
intBST.inorder(cout);
cout<<endl;
cout<<"\n\nNow testing the search() operation."<<endl;
cout<<"Item to find (-999 to stop):";
for(;;)
{
cin>>number;
if(number==-999)break;
cout<<(intBST.search(number)?"Found":"Not found" )<<endl;
}
cout<<"\n\nNow testing the remove() operation.\n";
cout <<"Item to remove (-999 to stop):";
for (;;)
{
cin>>number;
if(number==-999) break;
intBST.remove(number);
intBST.graph(cout);
}
cout<<"\nInorder Traversal of BST:\n";
intBST.inorder(cout);
cout<<endl;
}
//12 2 456 265 587 457 2745 2454 214752 -999