#include < iostream >
#include < string >
using namespace std ;template < typename elemType >
class BinaryTree ; //forward declarationtemplate < typename valType >
class BTnode { //Node of BinaryTree
public :
BTnode( ) ;
BTnode( const valType & ) ; //There is no need "const BTnode< valType >&"! because in this class , BTnode of course means "BTnode< valType >".
~BTnode( ) { }
BTnode& operator=( const BTnode & ) ;friend class BinaryTree< valType > ;
void insert_value( const valType & ) ;
void remove_value( const valType & , BTnode *& ) ; //Take care! reference to pointer: so we could change the pointer and the object.
static void lchild_leaf( BTnode *leaf , BTnode *subtree ) ;void preorder( BTnode *pt , ostream &os ) const ;
void inorder( BTnode *pt , ostream &os ) const ;
void postorder( BTnode *pt , ostream &os ) const ;private :
valType _val ;
int _cnt ; //Means the occurs of this node !
BTnode * _lchild ;
BTnode * _rchild ;void display( BTnode *pt , ostream &os ) const ; //const function only call const function!
} ;template < typename elemType >
class BinaryTree { //BinaryTree
public :
BinaryTree( ) ;
BinaryTree( const BinaryTree & ) ; //需要拷贝构造函数(需要申请空间)
~BinaryTree( ) ;
BinaryTree& operator=( const BinaryTree & ) ; //拷贝构造函数所需要的赋值运算符bool empty( ) const { return _root == 0 ; }
void clear( ) { if( _root ) { clear( _root ) ; _root = 0 ; } }void insert( const elemType &elem ) ;
void remove( const elemType & ) ;
void remove_root( ) ;void preorder( ) ;
void inorder( ) ;
void postorder( ) ;
private:
BTnode< elemType > *_root ;
//将src所指子树(subtree)复制到tar所指之子树 //copy the subtree of src to the subtree of tar
void copy( BTnode< elemType > *tar , BTnode< elemType > *src ) ;
void clear( BTnode< elemType > *pt ) ;
} ;//inline function 的声明和定义都必须在头文件中.
//****************************************************************************************//
//inline function!
template < typename valType >
inline BTnode< valType >::BTnode( ):_val( 0 ) //"_val( 0 )" maybe wrong!
{
_cnt = 0 ;
_lchild = 0 ;
_rchild = 0 ;
}template < typename valType >
inline BTnode< valType >::BTnode( const valType &val ):_val( val ) //because the "_val" maybe a class.
{
_cnt = 1 ;
_lchild = 0 ;
_rchild = 0 ;
}template < typename valType >
inline BTnode< valType >& BTnode< valType >::operator =( const BTnode &valelem )
{
if( this != &valelem )
{
_val = valelem->_val ;
_cnt = valelem->_cnt ;
_lchild = valelem->_lchild ;
_rchild = valelem->_rchild ;
}
return *this ;
}template < typename valType >
inline void BTnode< valType >::display( BTnode< valType > *pt , ostream &os ) const
{
os << "value: " << pt->_val << "\toccurs: " << pt->_cnt << endl ;
}//------------------------------------------// //non-inline
template < typename valType >
void BTnode< valType >::insert_value( const valType &elem )
{
if( elem == _val ) //The value equals the current Node.
{
_cnt++ ;
return ;
}if( elem < _val ) //go to left.
{
if( !_lchild )
_lchild = new BTnode< valType >( elem ) ;
else
_lchild->insert_value( elem ) ;
}
else // elem > _val .
{
if( !_rchild )
_rchild = new BTnode< valType >( elem ) ;
else
_rchild->insert_value( elem ) ;
}
}template < typename valType > //多看看
void BTnode< valType >::remove_value( const valType &val , BTnode *&prev ) //BTnode *&prev为下一个头
{
if( val < _val )
{
if( !_lchild )
return ;
else
_lchild->remove_value( val , _lchild ) ;
}
else
{
if( val > _val )
{
if( !_rchild )
return ;
else
_rchild->remove_value( val , _rchild ) ;
}
else //val == _val
{
if( _rchild )
{
prev = _rchild ;
if( _lchild )
{
if( !prev->_lchild )
prev->_lchild = _lchild ;
else
BTnode< valType >::lchild_leaf( _lchild , prev->_lchild ) ;
}
}
else
prev = _lchild ;delete this ;
}
}
}template < typename valType >
void BTnode< valType >::lchild_leaf( BTnode *leaf , BTnode *subtree )
{
while( subtree->_lchild )
subtree = subtree->_lchild ;
subtree->_lchild = leaf ;
}template < typename valType >
void BTnode< valType >::preorder( BTnode< valType > *pt , ostream &os ) const
{
if( pt )
{
display( pt , os ) ; //常函数只能调用常函数
// cout << pt->_val << ' ' ;
if( pt->_lchild ) preorder( pt->_lchild , os ) ;
if( pt->_rchild ) preorder( pt->_rchild , os ) ;
}
}template < typename valType >
void BTnode< valType >::inorder( BTnode< valType > *pt , ostream &os ) const
{
if( pt )
{
if( pt->_lchild ) inorder( pt->_lchild , os ) ;
display( pt , os ) ;
if( pt->_rchild ) inorder( pt->_rchild , os ) ;
}
}template < typename valType >
void BTnode< valType >::postorder( BTnode< valType > *pt , ostream &os ) const
{
if( pt )
{
if( pt->_lchild ) postorder( pt->_lchild , os ) ;
if( pt->_rchild ) postorder( pt->_rchild , os ) ;
display( pt , os ) ;
}
}//**************************************************************************************************************//
//inlinetemplate < typename elemType >
inline BinaryTree< elemType >::BinaryTree( ):_root( 0 )
{ }template < typename elemType >
inline BinaryTree< elemType >::BinaryTree( const BinaryTree &rhs )
{
copy( _root , rhs._root ) ;
}template < typename elemType >
inline BinaryTree< elemType >::~BinaryTree( )
{
clear( ) ;
}template < typename elemType >
inline BinaryTree< elemType >& BinaryTree< elemType >::operator =( const BinaryTree &rhs )
{
if( this != &rhs )
{
clear( ) ;
copy( _root , rhs._root ) ;
}
return *this ;
}template < typename elemType >
inline void BinaryTree< elemType >::copy( BTnode< elemType > *tar , BTnode< elemType > *src )
{
tar->_val = src->_val ;
tar->_cnt = src->_cnt ;
tar->_lchild = src->_lchild ;
tar->_rchild = src->_rchild ;
}template < typename elemType >
inline void BinaryTree< elemType >::insert( const elemType &elem )
{
if( !_root )
_root = new BTnode< elemType >( elem ) ;
else
_root->insert_value( elem ) ; //inline function can call the uninline function!
}template < typename elemType >
inline void BinaryTree< elemType >::remove( const elemType &elem )
{
if( _root )
{
if( _root->_val == elem )
remove_root( ) ; //It's special deal!
else
_root->remove_value( elem , _root ) ;
}
}//----------------------------------------------------// //non-inline
template < typename elemType >
void BinaryTree< elemType >::preorder( )
{
_root->preorder( _root , cout ) ;
}template < typename elemType >
void BinaryTree< elemType >::inorder( )
{
_root->inorder( _root , cout ) ;
}template < typename elemType >
void BinaryTree< elemType >::postorder( )
{
_root->postorder( _root , cout ) ;
}template < typename elemType >
void BinaryTree< elemType >::remove_root( )
{
if( !_root )
return ;BTnode< elemType > *temp = _root ;
if( _root->_rchild )
{
_root = _root->_rchild ;if( temp->_lchild ) //将左子结点搬移到右子节点的左子树的最底部
{
BTnode< elemType > *lc = temp->_lchild ;
BTnode< elemType > *newlc = _root->_lchild ;if( !newlc ) //没有任何子树,那么就直接接上
newlc = lc ; // _root->_lchild = temp->_lchild ;
else //lchild_leaf()遍历整个左子树,寻找某个可接上去的null左子结点。lchild_leaf是个static member function. ???
BTnode< elemType >::lchild_leaf( lc , newlc ) ; //通过类来调用,而不是通过对象来调用。所以lchild_leaf必须是个static member function.
//类是不分配内存的,除非在里面有声明的静态函数或变量,才会在程序的栈中分配内存
}
}
else
_root = _root->_lchild ;
delete temp ;
}template < typename elemType >
void BinaryTree< elemType >::clear( BTnode< elemType > *pt )
{
if( pt )
{
clear( pt->_lchild ) ;
clear( pt->_rchild ) ;
delete pt ;
}
}
//----------------------------------------------------------//
#include "BinaryTree.h"
int main( )
{
BinaryTree< string > bt ;bt.insert( "Piglet" ) ;
bt.insert( "Eeyore" ) ;
bt.insert( "Rooo" ) ;
bt.insert( "Tigget" ) ;
bt.insert( "Chris" ) ;bt.preorder( ) ;
cout << endl ;bt.remove( "Chris" ) ;
bt.inorder( ) ;
cout << endl ;bt.postorder( ) ;
cout << endl ;bt.clear( ) ;
return 0 ;
}
Binary Tree(C++)
最新推荐文章于 2023-07-22 01:06:43 发布