递归插入到二叉树中,按值传递指针

Recursively inserting into a binary tree, passing pointer by value?

本文关键字:按值传递 指针 二叉树 插入 递归      更新时间:2023-10-16

这是我的Node类。

class Node
{
private:
public:
  T data;
  Node<T>* left;
  Node<T>* right;
  Node(T dat) : data(dat), left(NULL), right(NULL)
  {}
};

这是我的插入函数,在我的Btree类中定义:

public:
  Node<T>* root;
  Btree() : root(NULL){}
  void insert(T data, Node<T>* parent)
  {   
      if( !parent  )
      {   
        parent = new Node<T>(data);
        return;
      }   
      else if(data < parent->data)
      {   
        insert(data, parent->left);
      }   
      else if(data > parent->data)
      {   
        insert(data, parent->right);
      }   
  }
};

这是我的主要功能:

int main()
{
  Btree<int> tree;
  tree.insert(5, tree.root);
  cout << tree.root->data << endl;
  tree.insert(6, tree.root);
  cout << tree.root->right->data << endl;
}

当我跑步时,我会出现seg错误。

我认为这是因为指针变量parent是通过值传递的,所以当我创建一个由parent指向的新Node时,一旦我退出insert函数,我就会丢失它?这是否意味着我必须在这里使用双指针?

有人能给我一个彻底的解释,说明记忆中发生了什么,使这件事没有按计划进行吗。我的诊断是正确的还是有其他问题?

当我传递tree.root作为第二个要插入的参数时,我传递的是Node*,我知道得太多了。现在,即使它是按值传递的,它也不会与我从调用主函数传递的地址相同。所以当我说parent(这是我从main传递的地址,tree.root)=new Node时,这不应该在parent的地址,也就是tree.root的地址的堆上创建一个新的Node吗?为什么忽略价值会混淆这一点?

在这种情况下传递值的问题是,对函数内的形式参数所做的所有赋值对调用方都不可见。因此,此任务

if( !parent  )
{   
    parent = new Node<T>(data); // <<== HERE
    return;
}

对调用方中的tree.root没有影响:

tree.insert(5, tree.root);

函数中parent指针的值发生更改,然后立即丢弃;树的CCD_ 3保持为CCD_。

解决这个问题的方法是将指针传递给一个指针,如下所示:

void insert(T data, Node<T>** parent) {
    if( !*parent  )
    {
        *parent = new Node<T>(data);
        return;
    }
    else if(data < (*parent)->data)
    {
        insert(data, &((*parent)->left));
    }
    else if(data > (*parent)->data)
    {
        insert(data, &((*parent)->right));
    }
}

C++按值传递,因此parent是传入指针的副本。因此,分配给它并没有持久的效果。解决此问题的最简单方法是更改方法的签名,使其接受对指针的引用。这将自动使编译器更新原始指针,同时避免必须更改程序的其余部分。

dasblinkenlight回答得最好。但是,还有一个更简洁的解决方案:

获取指针的引用(称为指针引用):

void insert(T data, Node<T>*& parent)
  {   
      if( !parent  )
      {   
        parent = new Node<T>(data);
        return;
      }   
      else if(data < parent->data)
      {   
        insert(data, parent->left);
      }   
      else if(data > parent->data)
      {   
        insert(data, parent->right);
      }   
  }

点击此处查看更多信息:http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer