自定义类_BinaryTree

该博客主要实现了二叉树类BinaryTree,包含结点插入、删除、遍历等操作。使用模版类解决元素类型匹配问题,同时指出多文件引用存在的错误及原因。最后通过main函数对二叉树的各项功能进行了测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

////////////////////////////////////////////////////////////
// 功能: 二叉树的实现
// 时间: 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);
 }
}

<think>好的,我现在需要解决用户在Python中遇到的BinaryTree()构造函数不接受参数的问题。用户提到参考了引用[1]中的内容,其中讨论了模式匹配中构造函数作为主动检查结构并提取字段的函数。这可能与用户的问题相关,即如何在Python中正确初始化BinaryTree的实例,确保构造函数能够接受必要的参数。 首先,我需要确认用户遇到的具体错误是什么。当用户说“BinaryTree()不接受参数”时,通常的错误信息可能是TypeError: __init__() takes 0 positional arguments but X were given,这意味着用户尝试传递参数给BinaryTree的构造函数,但该的__init__方法没有定义接受这些参数。 接下来,我需要分析可能的原因。常见的情况是用户定义了一个BinaryTree,但__init__方法没有正确声明参数。例如,可能用户写了似: class BinaryTree: def __init__(self): pass 这种情况下,实例化时如BinaryTree(5)就会报错,因为构造函数不接受参数。 解决方案应该是修改__init__方法,使其接受必要的参数。例如,如果用户希望每个二叉树节有一个值,构造函数应改为: class BinaryTree: def __init__(self, value): self.value = value self.left = None self.right = None 这样实例化时就可以传递参数,如node = BinaryTree(5)。 另外,根据引用[1]中的内容,构造函数可能需要主动检查结构并提取字段,因此可能需要更复杂的初始化逻辑。例如,如果用户希望构造函数可以接受不同的参数形式,或者进行型检查,这需要在__init__方法中实现。 可能的错误还有用户没有正确继承父,或者在子中覆盖了__init__但没有调用父的构造函数,导致参数传递失败。例如,如果用户定义了一个子,但未正确使用super().__init__(),可能会引发错误。 此外,用户可能在使用第三方库中的BinaryTree,而该的构造函数设计为不接受参数。这时需要查阅该库的文档,确认正确的使用方法,或者可能需要扩展该以适应参数需求。 总结可能的解决步骤: 1. 检查用户自定义BinaryTree的__init__方法,确认参数是否正确。 2. 确保实例化时传递的参数与__init__定义的参数匹配。 3. 如果使用继承,确保正确调用父的构造函数。 4. 若使用第三方库,查阅文档或考虑扩展。 接下来需要验证这些可能性。例如,用户可能没有在__init__中定义参数,导致无法传参。修改__init__以接受参数即可解决。同时,引用[1]提到的构造函数作为主动检查函数,可能需要在初始化时进行结构验证,比如确保传入的参数符合二叉树节的结构要求,如包含左右子节或值属性。 最后,生成相关问题,帮助用户深入理解构造函数的使用和可能的优化方法。</think>在Python中遇到`BinaryTree()`构造函数报错不接受参数的问题,通常是因为初始化方法`__init__`未定义参数,但实例化时传递了参数。以下是具体分析及解决方案: --- ### **问题分析** 1. **错误示例** 当尝试执行`node = BinaryTree(5)`时,若定义为: ```python class BinaryTree: def __init__(self): # 未定义参数 self.left = None self.right = None ``` 会触发错误:`TypeError: __init__() takes 1 positional argument but 2 were given`,因为构造函数未声明接受`value`参数。 2. **根本原因** - `__init__`方法未定义参数(如`value`),无法接收实例化时传入的值。 - 若使用第三方库的`BinaryTree`,可能其设计默认不接受参数[^1]。 --- ### **解决方案** #### 1. **修改自定义类的构造函数** 若`BinaryTree`是用户自定义类,需在`__init__`中声明参数: ```python class BinaryTree: def __init__(self, value): # 添加value参数 self.value = value self.left = None self.right = None # 实例化时传递参数 node = BinaryTree(5) ``` #### 2. **处理继承或第三方库的情况** - **继承父**:若继承自其他(如第三方库的二叉树),需确保正确调用父构造函数: ```python class MyBinaryTree(BinaryTree): def __init__(self, value): super().__init__() # 若父不接受参数 self.value = value # 额外添加属性 ``` - **扩展第三方**:若第三方的构造函数不接受参数,但需要添加属性,可通过包装或扩展实现。 #### 3. **参数默认值(可选)** 若希望参数可选,可为`__init__`设置默认值: ```python class BinaryTree: def __init__(self, value=None): # 允许不传参,默认value为None self.value = value self.left = None self.right = None # 实例化时可传参或不传 node1 = BinaryTree() # 有效 node2 = BinaryTree(5) # 有效 ``` --- ### **代码验证** 修改后的完整示例: ```python class BinaryTree: def __init__(self, value): self.value = value self.left = None self.right = None # 正确实例化 root = BinaryTree(10) root.left = BinaryTree(5) root.right = BinaryTree(15) print(root.value) # 输出: 10 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值