我正在尝试使用两种方法删除示例二叉搜索树的左子节点 (10):
- 方法 1:通过将指针传递给指向当前节点的指针。
- 方法2:通过将指针的地址传递给当前节点。这不会删除节点,但调用 delete 会破坏指针排列,导致打印节点时发生崩溃。
树看起来像这样,我正在尝试删除 10 并用 5 替换它
20 | 10--|---30 | 5---|
我对指针有一些了解。但是,我仍然不清楚指针的这种行为。
#include <iostream>
class Node
{
public:
Node(int key) : leftChild(0), rightChild(0), m_key (key){}
~Node(){}
Node *leftChild;
Node *rightChild;
int m_key;
};
Node* build1234(int, int, int, int);
void print(Node *);
void print1234(Node *);
void removeLeft(Node **nodePtr)
{
Node *oldPtr = *nodePtr;
if(*nodePtr)
{
*nodePtr = (*nodePtr)->leftChild;
delete oldPtr;
}
}
int main()
{
Node *demo1 = build1234(10, 20, 30, 5);
Node *demo2 = build1234(10, 20, 30, 5);
print1234(demo1);
print1234(demo2);
//Method1 - 10 is correctly removed with 5
Node **nodePtr = &demo1;
nodePtr = &(*nodePtr)->leftChild;
removeLeft(nodePtr);
print1234(demo1);
//Method2 - 10 is not removed
Node *node = demo2;
node = node->leftChild;
removeLeft(&node);
print1234(demo2);
return 0;
}
Node* build1234(int B, int A, int C, int D)
{
Node *root = new Node(A);
root->leftChild = new Node(B);
root->rightChild = new Node(C);
root->leftChild->leftChild = new Node(D);
return root;
}
void print(Node *node)
{
if(node)
{
print(node->leftChild);
std::cout << "[" << node->m_key << "]";
print(node->rightChild);
}
}
void print1234(Node *node)
{
std::cout << std::endl;
print(node);
}
注意:这道题不是BST,而是指针。如果您在 main()
函数中看到对 removeLeft(nodePtr)
和 removeLeft(&node)
的两次调用。
- 这两者有何不同?
- 为什么第二种方法达不到预期的效果?
最佳答案
在第一种情况下,您传递的是树中存在的指针的地址,因此您是在直接修改树的内容。
在第二种情况下,您传递的是 main() 局部变量的地址。树没有修改,从地址删除是访问栈内存,所以崩溃
关于c++ - 指针 - 将 ptr 传递给 ptr 或传递 ptr 的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7945585/