[英]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
( N
为NULL
)在发布的while
循环完成后:
trailingNode
指向值为4
的Node
curr
为NULL
( Node
的左分支,值为4
) 然后insert()
将一个新的Node
分配给curr
但切勿将其附加到值为4
的Node
的左分支上。
要附加,可以将调用更改为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();
现在,您可以看到它实际上并未在树中插入任何内容。 现在,如果您想要一个变量来指示节点的实际left
或right
成员,而不仅仅是具有与该成员相同的值(指向同一对象),则需要有一个指向该成员(字段)本身的指针-由于成员的类型为“指向Node
的指针”,所以指向该成员的指针必须是指向(指向Node
指针)的指针,或者使用C ++表示法Node**
。
现在,如果将“指向指针的指针”传递给函数,则可以通过它修改所引用的left
成员或right
成员的值。 这也意味着您不需要修改curr
的值(并因此通过引用将其传递)-它仍将指向相同的left
或right
成员(或可能是BalancedTree
对象的root
成员),而仅指向该成员的值将更改为指向新创建的元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.