C++ 二叉树:复制构造函数

C++ 二叉树:复制构造函数,c++,binary-tree,binary-search-tree,C++,Binary Tree,Binary Search Tree,我必须用签名bstt(const-bstt&other)为二叉树创建一个副本构造函数。我试图这样做,但我得到了以下错误(在最后一个代码块中) 我想我需要更改我的helper函数签名以包含一个常量,但我尝试了几个组合,但没有一个有效。我怎样才能解决这个问题 辅助功能: void _postordercopy(NODE*& thisT, const NODE*& otherT) { if(otherT==nullptr){ thisT=nullptr; } else {

我必须用签名
bstt(const-bstt&other)
为二叉树创建一个副本构造函数。我试图这样做,但我得到了以下错误(在最后一个代码块中)

我想我需要更改我的helper函数签名以包含一个
常量
,但我尝试了几个组合,但没有一个有效。我怎样才能解决这个问题

辅助功能:

void _postordercopy(NODE*& thisT, const NODE*& otherT)
{
 if(otherT==nullptr){
  thisT=nullptr;
 }
 else
 {
  NODE* tmp=new NODE;
  tmp->Key=otherT->Key;
  tmp->Value=otherT->Value;
  tmp->Left=otherT->Left;
  tmp->Right=otherT->Right; 
  tmp->isThreaded=otherT->isThreaded;

  _postordercopy(thisT->Left,otherT->Left);
  _postordercopy(thisT->Right,otherT->Right);
 }
}
    NODE* copyTree(const NODE* other)
    {
         NODE* newTree = nullptr;

         if (other!=nullptr)
         {
             newTree = new NODE;
             newTree->Key = other->Key;
             newTree->Value = other->Value;
             newTree->isThreaded = other->isThreaded;
             newTree->Left = copyTree(other->Left);
             newTree->Right = copyTree(other->Right);
         }

         return newTree;
    }
复制构造函数:

  bstt(const bstt& other)
  {
   Size=other.Size;
   _postordercopy(Root,other.Root);
  }
错误消息:

bstt.h:110:35: error: no matching function for call to ‘bstt<int, int>::_postordercopy(bstt<int, int>::NODE*&, bstt<int, int>::NODE* const&)’
bstt.h:110:35:错误:调用“bstt::_postordercopy(bstt::NODE*&,bstt::NODE*const&)”时没有匹配的函数

您正在
\u postordercopy
函数中创建一个
tmp
节点,分配给它,但没有对它执行任何操作。此外,您正在复制左和右的精确指针。这看起来也不对

我认为这正是递归“复制树”函数真正想要的:

void _postordercopy(NODE*& thisT, const NODE*& otherT)
{
 if(otherT==nullptr){
  thisT=nullptr;
 }
 else
 {
  NODE* tmp=new NODE;
  tmp->Key=otherT->Key;
  tmp->Value=otherT->Value;
  tmp->Left=otherT->Left;
  tmp->Right=otherT->Right; 
  tmp->isThreaded=otherT->isThreaded;

  _postordercopy(thisT->Left,otherT->Left);
  _postordercopy(thisT->Right,otherT->Right);
 }
}
    NODE* copyTree(const NODE* other)
    {
         NODE* newTree = nullptr;

         if (other!=nullptr)
         {
             newTree = new NODE;
             newTree->Key = other->Key;
             newTree->Value = other->Value;
             newTree->isThreaded = other->isThreaded;
             newTree->Left = copyTree(other->Left);
             newTree->Right = copyTree(other->Right);
         }

         return newTree;
    }
然后在复制构造函数中,按如下方式调用它:

    bstt(const bstt& other)
    {
        this->Size = other.Size;
        this->Root = copyTree(other.Root);
    }
我将假定
bstt::Root
被声明为
NODE*
,这似乎是最有可能的

\u postordercopy
的第二个参数的类型为
常量节点*&
,是指向常量
节点的指针的引用。您试图传递的参数类型是什么?由于
other
被声明为
const
,因此其每个成员都是
const
。因此
other.Root
是指向
节点的常量指针,也称为
节点*const
const
固定在声明类型的最右侧。这与参数类型不兼容。(有关此区别的更详细讨论,请参阅。)

问题是非常量引用不能从常量初始化。由于
other
必须是
const
,因此您需要更改函数参数的类型,以匹配您给定的类型。一种解决方案是移动
const
,使其限定指针而不是指向对象的指针:
NODE*const&
。另一种解决方案是删除符号AND,因为在本例中这有点浪费:
const NODE*
。(参考添加了一个额外的间接层,没有提供任何好处。)想想你的函数应该做什么,然后
const
-限定任何应该不改变的内容。在这种情况下,第二个参数指向的节点不应更改

虽然这可以解决即时编译器错误,但代码中还有其他错误需要解决。另外,我会考虑添加两个访问器函数来获取根节点。这些函数可以强制执行
const
,而直接访问
Root
时无法实现

NODE *& get_root() { return Root; }
const NODE * const & get_root() const { return Root; }

主要区别在于
other.Root
的类型是
NODE*const
,它删除了节点的
const
-限定符,而
other.get_Root()
将生成一个
const NODE*const
,它传播限定符。同时,
this->get_root()
将产生一个简单的
节点*
,因为
this
不是
常量
限定的。您可以使用相同的语法,并且适当地传播
const
-ness。

在函数
bsst(const bsst&)
中,变量
other
const
。这意味着您已向调用此函数的任何人提供了一份合同,
other
将不会被修改
bsst(const bsst&)
无法将
其他
发送到
\u postordercopy
,因为它不知道
\u postordercopy
是否会对
其他
进行任何更改。更改
\u postordercopy
的函数签名,使第二个参数为
const Node*&otherT
,这样副本构造函数就可以遵守自己的
const
契约。@John我得到错误:
参数2从'bstt::NODE*'到'const bstt::NODE*&'没有已知的转换。
我想给它想要的签名。我对
const
规则没有我想的那么清楚。