繁体   English   中英

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

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

我正在为类编写一个平衡的二进制树,但是对于如何在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);
}

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

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

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

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

然后insert()将一个新的Node分配给curr但切勿将其附加到值为4Node的左分支上。

要附加,可以将调用更改为insert()

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

当树为空时,您需要处理这种情况。 有迹象表明,这可以实现,但希望这将指向你在正确的方向上的其它方式。

您可以使用双指针进行操作。 使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);
}

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

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
}

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

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

Node curr;

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

现在,您可以看到它实际上并未在树中插入任何内容。 现在,如果您想要一个变量来指示节点的实际leftright成员,而不仅仅是具有与该成员相同的值(指向同一对象),则需要有一个指向该成员(字段)本身的指针-由于成员的类型为“指向Node的指针”,所以指向该成员的指针必须是指向(指向Node指针)的指针,或者使用C ++表示法Node**

现在,如果将“指向指针的指针”传递给函数,则可以通过它修改所引用的left成员或right成员的值。 这也意味着您不需要修改curr的值(并因此通过引用将其传递)-它仍将指向相同的leftright成员(或可能是BalancedTree对象的root成员),而仅指向该成员的值将更改为指向新创建的元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM