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

时间:2012-02-17 08:04:10

标签: c++

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

void BalancedTree::insert(int input)
{
    cout << "Insert started\n"; //DEBUG
    Node* trailingNode;
    Node* curr;

    curr = this->root;

    while(curr != NULL){
        cout << "Addloop\n";    //Debug
        if(input < curr->data){     //input smaller than current
            cout << "Left\n"; //DEBUG
            trailingNode = curr;
            curr = curr->left;
        }else{                      //input larger than current node
            cout << "Right\n"; //DEBUG
            trailingNode = curr;
            curr = curr->right;
        }
    }   

    insert(curr, input);
    cout << "test" << endl; 
    cout << root->data << " added\n";   //DEBUG
//  curr->parent = trailingNode;    //Set the parent

    size++;                         //Increase size
}

//Helper method
void BalancedTree::insert(Node*& curr, int input)
{
    curr = new Node(input);
}

4 个答案:

答案 0 :(得分:1)

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

             2
            / \
       1 <--   --> 4
      / \         / \
     N   N       N   N
发布后的N循环完成后,

NULLwhile}:

  • trailingNode指向Node,其值为4
  • currNULLNode的左侧分支,值为4

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

要附加,您可以将通话更改为insert()

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

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

答案 1 :(得分:0)

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

    Node ** curr;
    curr = &this->root;

    while(*curr != NULL){
        cout << "Addloop\n";    //Debug
        if(input < (*curr)->data){     //input smaller than current
            cout << "Left\n"; //DEBUG
            trailingNode = curr;
            curr = &((*curr)->left);
        }else{                      //input larger than current node
            cout << "Right\n"; //DEBUG
            trailingNode = curr;
            curr = &((*curr)->right);
        }
    }   

    insert(curr, input);
    cout << "test" << endl; 
    cout << root->data << " added\n";   //DEBUG
//  curr->parent = trailingNode;    //Set the parent

    size++;                         //Increase size
}

//Helper method
void BalancedTree::insert(Node** curr, int input)
{
    *curr = new Node(input);
}

我认为这应该适合你,但还没试过 - 只是在编辑中进行了编辑,所以如果我做了一些简单的编码错误,请原谅我。

答案 2 :(得分:0)

1)将指针初始化为NULL:

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

2)不需要在while循环中显式检查NULL:

while(curr){

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

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

答案 3 :(得分:0)

指针是值类型,类似于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成员(或可能root对象的BalancedTree成员,只会将该成员的值更改为指向新创建的元素。