我正在为类编写一个平衡二叉树,但是我对如何在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);
}
答案 0 :(得分:1)
如果我们有以下树并尝试插入值3
:
2
/ \
1 <-- --> 4
/ \ / \
N N N N
发布后的N
循环完成后,(NULL
为while
}:
trailingNode
指向Node
,其值为4
curr
为NULL
(Node
的左侧分支,值为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();
现在您可以看到这实际上并没有在树中插入任何内容。现在,如果您希望变量指示节点的实际left
或right
成员,而不是仅具有与该成员相同的值(指向同一对象),则需要指向成员(字段)本身的指针 - 由于成员是'Node
'指针的类型,指向成员的指针必须是指向(Node
的指针)的指针,或者C ++表示法Node**
。
现在,如果将“指针指针”传递给函数,则可以通过它修改引用的left
或right
成员的值。这也意味着您无需修改curr
的值(因此通过引用将其传入) - 它仍将指向相同的left
或right
成员(或可能root
对象的BalancedTree
成员,只会将该成员的值更改为指向新创建的元素。