簡體   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