将节点附加到C++树(参考和指针帮助)

Attaching nodes to a tree in C++ (Reference and pointer help.)

本文关键字:参考 指针 帮助 节点 C++      更新时间:2023-10-16

我正在为类编写一个平衡二叉树,但我对如何在C++中使用指针和引用(直接来自Java(有些困惑。下面的代码导致段错误,因为实际上没有节点添加到树中,curr刚刚切换到新的Node。我将如何使新Node转到树上curr指向的位置,而不仅仅是重新分配curr

void BalancedTree::insert(int input)
{
    cout << "Insert startedn"; //DEBUG
    Node* trailingNode;
    Node* curr;
    curr = this->root;
    while(curr != NULL){
        cout << "Addloopn";    //Debug
        if(input < curr->data){     //input smaller than current
            cout << "Leftn"; //DEBUG
            trailingNode = curr;
            curr = curr->left;
        }else{                      //input larger than current node
            cout << "Rightn"; //DEBUG
            trailingNode = curr;
            curr = curr->right;
        }
    }   
    insert(curr, input);
    cout << "test" << endl; 
    cout << root->data << " addedn";   //DEBUG
//  curr->parent = trailingNode;    //Set the parent
    size++;                         //Increase size
}
//Helper method
void BalancedTree::insert(Node*& curr, int input)
{
    curr = new Node(input);
}

如果我们有以下树并尝试插入值3

             2
            / 
       1 <--   --> 4
      /          / 
     N   N       N   N

( NNULL ( 在发布的while循环完成后:

  • trailingNode指向具有值4Node
  • currNULL(值为 4Node的左分支(

然后insert()curr分配一个新Node,但从不将其附加到值为 4Node的左侧分支。

要附加,您可以将呼叫更改为insert()

insert(input < trailingNode->data ?
           trailingNode->left :
           trailingNode->right,
       input);

您需要处理树为空的情况。 还有其他方法可以实现这一点,但希望这将为您指明正确的方向。

您可以使用双指针来做到这一点。使cur实际引用(在C++情况下指向(您需要更改的最后一个节点引用:

    Node ** curr;
    curr = &this->root;
    while(*curr != NULL){
        cout << "Addloopn";    //Debug
        if(input < (*curr)->data){     //input smaller than current
            cout << "Leftn"; //DEBUG
            trailingNode = curr;
            curr = &((*curr)->left);
        }else{                      //input larger than current node
            cout << "Rightn"; //DEBUG
            trailingNode = curr;
            curr = &((*curr)->right);
        }
    }   
    insert(curr, input);
    cout << "test" << endl; 
    cout << root->data << " addedn";   //DEBUG
//  curr->parent = trailingNode;    //Set the parent
    size++;                         //Increase size
}
//Helper method
void BalancedTree::insert(Node** curr, int input)
{
    *curr = new Node(input);
}

我认为这应该可以为您解决问题,但还没有尝试过 - 只是在这里编辑,所以如果我犯了一些简单的编码错误,请原谅我。

1( 初始化指向 NULL 的指针:

Node* trailingNode = NULL;
Node* curr = NULL;

2( 无需在 while 循环中显式检查 NULL:

while(curr){

3( 对insert(curr, input)的调用始终使用 NULL 指针调用!即使它不是 NULL,该指针仍然只是一个常规指针,与您从中检索它的节点无关。引用它不会解决此问题。相反,您需要创建一个新节点并将其分配给尾随节点的左侧或右侧,例如:

if (!curr->right) {
    curr->right = new Node (input);
    break; // exit while
}
指针

是值类型,类似于Java中的引用或整数。

通过引用传递变量会创建该变量的别名,因此您可以在函数中更改其值。当你执行insert(curr, input);时,它会修改指针变量curr的值,使其指向一个新创建的节点。Java 中或多或少等效的情况是:

Node curr;
if([...]) {
    [...]
    curr = curr.left;
}
else {
    [...]
    curr=curr.right;
}
[...]
curr = new Node();

现在您可以看到这实际上并没有将任何内容插入树中。现在,如果您希望变量指示节点的实际leftright成员,而不仅仅是具有与该成员相同的值(指向同一对象(,您需要有一个指向成员(字段(本身的指针 - 因为成员的类型是"指向Node的指针", 指向成员的指针必须是指向(指向Node的指针(,或者C++表示法Node**

现在,如果将该"指针指向指针"传递给函数,则可以通过它修改引用的leftright成员的值。这也意味着您不需要修改 curr 的值(因此通过引用传入( - 它仍将指向相同的leftright成员(或者可能是 BalancedTree 对象的root成员(,只有该成员的值将被更改为指向新创建的元素。