自定义类_BinaryTree


// 功能: 二叉树的实现
// 时间: 2005-11-12
//
// BUG:
// 以多文件方式引用会引起错误
// 原因为:
// 在 BinaryTree类 的声明中
// 定义 struct tagBinaryTreeNode
// BinaryTree为模版类,template<class Type>
// 在 struct tagBinaryTreeNode 中有元素类型为Type
// Type value;
// 如果放在 BinaryTree外,
// 怎么使 tagBinaryTreeNode.value 的类型与 Type 匹配



// BinaryTree类的声明部分
//
#define BTREE_ERROR 0
#define BTREE_LEFT 1
#define BTREE_RIGHT 2
#define NULL 0

template<class Type>
class BinaryTree
{
 public:
  typedef struct tagBinaryTreeNode
  {
   Type value;
   struct tagBinaryTreeNode *left;
   struct tagBinaryTreeNode *right;
   struct tagBinaryTreeNode *parent;
  } BNODE , *BLIST , *BPOINT;

 public:
  BinaryTree();
  ~BinaryTree();

  //清空二叉树
  void Clear();
  //将结点e赋值为value
  void Assign( Type value , BPOINT e = NULL );
  //插入结点
  void InsertChild( BPOINT e , Type value , int LRFlag = BTREE_LEFT );
  //删除子树
  void DeleteChildren( BPOINT e , int LRFlag );
  void DeleteChildren( BPOINT e );
  //父结点指针
  BPOINT Parent( BPOINT e );
  //子结点指针
  BPOINT Child( BPOINT e , int LRFlag = BTREE_LEFT );
  //兄弟结点指针
  BPOINT Sibling( BPOINT e );
  //判断结点e是父结点的 左孩子 or 右孩子
  int GetLRFlag( BPOINT e );
  //根结点指针
  BPOINT Root();
  //得到指定结点的值
  Type GetValue( BPOINT e );
  //前序遍历二叉树
  BPOINT PreOrderTraverseFirst();
  BPOINT PreOrderTraverseNext( BPOINT e );
  //中序遍历二叉树
  BPOINT InOrderTraverseFirst();
  BPOINT InOrderTraverseNext( BPOINT e );
  //后序遍历二叉树
  BPOINT PostOrderTraverseFirst();
  BPOINT PostOrderTraverseNext( BPOINT e );
 private:
  //中序遍历
  void InOrderTraverse( BPOINT e );

 private:
  BLIST root;
};


// BinaryTree类的实现部分
//
template<class Type>
BinaryTree<Type>::BinaryTree()
{
 //cout<<"hi, i am in constructor of BinaryTree"<<endl;
 root = NULL;
}

template<class Type>
BinaryTree<Type>::~BinaryTree()
{
 //cout<<"hi, i am in deconstructor of BinaryTree"<<endl;
 DeleteChildren( root );
}

//
//清空二叉树
template<class Type>
void BinaryTree<Type>::Clear()
{
 DeleteChildren( root );
 root = NULL; 
}
//
//如果指定e,则将结点e赋值为value
//如果没有指定e,则默认结点为root
//如果是空树,即root==NULL,则建立root结点
template<class Type>
void BinaryTree<Type>::Assign( Type value , BPOINT e )
{
 if( e == NULL )
 {
  if( root == NULL )
  {
   root = new BNODE;
   root->value = value;
   root->left = NULL;
   root->right = NULL;
   root->parent = NULL;
  }
  else
  {
   root->value = value;
  }
 }
 else
 {
  e->value = value;
 }
}
//
//插入结点
template<class Type>
void BinaryTree<Type>::InsertChild( BPOINT e , Type value , int LRFlag )
{
 if( e == NULL )
  return;
 BPOINT child = new BNODE;
 child->value = value;
 child->left = NULL;
 child->right = NULL;
 child->parent = e;
 //判断要插入的位置,即左右边
 if( LRFlag == BTREE_LEFT )
 {
  if( e->left != NULL )
  {
   //如果e的左子树不空,
   //则将其作为child结点的左子树
   child->left = e->left;
   e->left->parent = child;
   e->left = child;
  }
  else
  {
   e->left = child;
  }
 }
 else
 {
  if( e->right != NULL )
  {
   //如果e的右子树不空,
   //则将其作为child结点的右子树
   child->right = e->right;
   e->right->parent = child;
   e->right = child;
  }
  else
  {
   e->right = child;
  }
 }
}
//
//删除子树
template<class Type>
void BinaryTree<Type>::DeleteChildren( BPOINT e , int LRFlag )
{
 if( LRFlag & BTREE_LEFT )
 {
  DeleteChildren( e->left );
  e->left = NULL;
 }
 if( LRFlag & BTREE_RIGHT )
 {
  DeleteChildren( e->right );
  e->right = NULL;
 }
}
template<class Type>
void BinaryTree<Type>::DeleteChildren( BPOINT e )
{
 if( e != NULL )
 {
  DeleteChildren( e->left );
  DeleteChildren( e->right );
  if( e != root )
  {
   if( e->parent->left == e )
    e->parent->left = NULL;
   if( e->parent->right == e )
    e->parent->right = NULL;
  }
  else
  {
   root = NULL;
  }
  delete e;
 }
}
//
//得到父结点的指针
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::Parent( BPOINT e )
{
 if( e == NULL )
  return NULL;
 return e->parent;
}
//
//得到子结点的指针
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::Child( BPOINT e , int LRFlag )
{
 if( e == NULL )
  return NULL;
 if( LRFlag == BTREE_LEFT )
 {
  return e->left;
 }
 else
 {
  return e->right;
 }
}
//
//得到根结点的指针
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::Root()
{
 return root;
}
//
//得到兄弟结点的指针
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::Sibling( BPOINT e )
{
 if( e == root || e == NULL )
  return NULL;
 if( e->parent->left == e )
  return e->parent->right;
 else
  return e->parent->left;
}
//
//判断结点e是父结点的 左孩子 or 右孩子
template<class Type>
int BinaryTree<Type>::GetLRFlag( BPOINT e )
{
 if( e == NULL || e == root )
  return BTREE_ERROR;
 if( e->parent->left == e )
  return BTREE_LEFT;
 else
  return BTREE_RIGHT;
}
//
//得到指定结点的值
template<class Type>
Type BinaryTree<Type>::GetValue( BPOINT e )
{
 if( e == NULL )
  return 0;
 return e->value;
}
//
//前序遍历二叉树
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::PreOrderTraverseFirst()
{
 return root;
}
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::PreOrderTraverseNext( BPOINT e )
{
 if( e->left != NULL )
 {
  return e->left;
 }
 else if( e->right != NULL )
 {
  return e->right;
 }
 else
 {
  while( e != NULL && e != root && ( GetLRFlag( e ) == BTREE_RIGHT || e->parent->right == NULL ) )
  {
   e = e->parent;
  }
  if( e == NULL || e == root )
   return NULL;
  else
   return e->parent->right;
 }
}
//
//中序遍历二叉树
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::InOrderTraverseFirst()
{
 if( root == NULL )
  return NULL;
 BPOINT e = root;
 while( e->left != NULL )
  e = e->left;
 return e;
}
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::InOrderTraverseNext( BPOINT e )
{
 if( e == NULL )
  return NULL;
 BPOINT p;
 if( e->right != NULL )
 {
  p = e->right;
  while( p->left != NULL )
   p = p->left;
  return p;
 }
 else
 {
  p = e;
  while( GetLRFlag( p ) == BTREE_RIGHT && p != NULL && p != root )
   p = p->parent;
  return p->parent;
 }
}
//
//后序遍历二叉树
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::PostOrderTraverseFirst()
{
 if( root == NULL )
  return NULL;
 BPOINT e = root;
 while( e->left != NULL )
  e = e->left;
 return e;
}
template<class Type>
BinaryTree<Type>::BPOINT BinaryTree<Type>::PostOrderTraverseNext( BPOINT e )
{
 if( e == NULL || e == root )
  return NULL;

 BPOINT p = Sibling( e );
 if( GetLRFlag(e) == BTREE_LEFT && p != NULL )
 {
  while( p->left != NULL )
   p = p->left;
  return p;
 }
 else
 {
  return e->parent;
 }
}
//
//


#include "iostream.h"

void main()
{
 int flag;

 BinaryTree<int> btree;
 BinaryTree<int>::BPOINT p;

btree.Clear();
 btree.Assign( 17 );
 btree.InsertChild( btree.Root() , 16 , BTREE_LEFT );
 btree.InsertChild( btree.Root() , 18 , BTREE_RIGHT );
 btree.InsertChild( btree.Child( btree.Root() , BTREE_RIGHT ) , 19 , BTREE_LEFT );
//btree.DeleteChildren( btree.Root()->left->parent->right );

 cout<<"value of root is ";
 cout<<btree.GetValue( btree.Root() )<<endl;


 cout<<"根结点的 左孩子 是 根结点的 ";
 flag = btree.GetLRFlag( btree.Child( btree.Root() , BTREE_LEFT ) );
 if( flag == BTREE_LEFT )
  cout<<"左孩子"<<endl;
 else if( flag == BTREE_RIGHT )
  cout<<"右孩子"<<endl;
 else
  cout<<"!!!出错!!!"<<endl;


 cout<<"根结点的 左孩子 ";
 flag = btree.GetLRFlag( btree.Sibling( btree.Child( btree.Root() , BTREE_LEFT ) ) );
 if( flag & BTREE_LEFT )
  cout<<"的 兄弟是 根结点的 左孩子"<<endl;
 else if( flag & BTREE_RIGHT )
  cout<<"的 兄弟是 根结点的 右孩子"<<endl;
 else
  cout<<"没有兄弟"<<endl;

 cout<<btree.Root()<<"/t"<<btree.GetValue( btree.Root() )<<endl;
 cout<<btree.Child( btree.Root() , BTREE_LEFT )<<"/t"<<btree.GetValue(btree.Child( btree.Root() , BTREE_LEFT ))<<endl;
 cout<<btree.Sibling( btree.Child( btree.Root() , BTREE_LEFT ) )<<"/t"<<btree.GetValue(btree.Sibling( btree.Child( btree.Root() , BTREE_LEFT ) ))<<endl;

 cout<<"前序:"<<endl;
 p = btree.PreOrderTraverseFirst();
 while( p )
 {
  cout<<btree.GetValue(p)<<endl;
  p = btree.PreOrderTraverseNext(p);
 }


 cout<<"中序:"<<endl;
 p = btree.InOrderTraverseFirst();
 while( p )
 {
  cout<<btree.GetValue(p)<<endl;
  p = btree.InOrderTraverseNext(p);
 }

 cout<<"后序:"<<endl;
 p = btree.PostOrderTraverseFirst();
 while( p )
 {
  cout<<btree.GetValue(p)<<endl;
  p = btree.PostOrderTraverseNext(p);
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值