Binary Tree(C++)

#include < iostream >
#include < string >
using namespace std ;

template < typename elemType >
class BinaryTree ;              //forward declaration

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

//**************************************************************************************************************//
                 //inline

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值