为什么我的C++代码无法删除我的BST中的所有节点?
这将遍历BST并删除每个节点,包括根节点。然而,在最后,我得到的消息根仍然有一个左节点。为什么没有删除所有节点为什么我的C++代码无法删除我的BST中的所有节点?,c++,pointers,binary-tree,binary-search-tree,C++,Pointers,Binary Tree,Binary Search Tree,这将遍历BST并删除每个节点,包括根节点。然而,在最后,我得到的消息根仍然有一个左节点。为什么没有删除所有节点 void deleteTree() { deleteNode(root); if(root->right) cout << "root still has a right node" << endl; if(root->left) cout << "root still has
void deleteTree()
{
deleteNode(root);
if(root->right)
cout << "root still has a right node" << endl;
if(root->left)
cout << "root still has a left node" << endl;
root = 0;
}
void deleteNode(node *p)
{
if(p->left)
{
deleteNode(p->left);
p->left = 0;
}
if(p->right)
{
deleteNode(p->right);
p->right = 0;
}
cout << "Deleting node containing " << p->data << endl;
delete p;
}
您正在删除根末尾的p,然后尝试访问deleteTree中的内容,其中根不再指向已分配的内存。结果将是未定义的。您正在删除根末尾的p,然后尝试在deleteTree中访问其内容,根不再指向已分配的内存。结果将是未定义的。您正在删除根目录。然后你的代码试图访问它所在的内存
您已经进入了未定义的行为领域。您正在删除root。然后你的代码试图访问它所在的内存
您已经进入了未定义的行为领域。在deleteNode中删除root之后,不应该取消对它的引用。使用调试器检查root->left为何为非null。在deleteNode中删除root之后,不应取消对其的引用。使用调试器检查为什么root->left为非null。您在删除root之后查看root->left,使其可用于新分配的块。您在删除root之后查看root->left,使其可用于新分配的块。我只需更改树本身,那就更容易处理了:
struct Node
{
Node(data_type data): mLeft(), mRight(), mData(data) {}
Node(const Node& rhs): mLeft(), mRight(), mData(rhs.mData)
{
if (rhs.mLeft.get()) mLeft.reset(new Node(*rhs.mLeft));
if (rhs.right.get()) mRight.reset(new Node(*rhs.mRight));
}
Node& operator=(Node rhs)
{
this->swap(rhs);
return *this;
}
~Node() { }
void swap(Node& rhs)
{
using std::swap;
swap(mLeft, rhs.mLeft);
swap(mRight, rhs.mRight);
swap(mData, rhs.mData);
}
Node* left() const { return mLeft.get(); }
void left(std::auto_ptr<Node> node) { mLeft= node; }
Node* right() const { return mRight.get(); }
void right(std::auto_ptr<Node> node) { mRight = node; }
data_type& data() { return mData; }
const data_type& data() const { return mData; }
private:
std::auto_ptr<Node> mLeft;
std::auto_ptr<Node> mRight;
data_type mData;
};
虽然C++可以防止意外的问题,但它对邪恶代码敞开了大门。 < p>我只需简单地改变树本身,就可以更容易地处理它:
struct Node
{
Node(data_type data): mLeft(), mRight(), mData(data) {}
Node(const Node& rhs): mLeft(), mRight(), mData(rhs.mData)
{
if (rhs.mLeft.get()) mLeft.reset(new Node(*rhs.mLeft));
if (rhs.right.get()) mRight.reset(new Node(*rhs.mRight));
}
Node& operator=(Node rhs)
{
this->swap(rhs);
return *this;
}
~Node() { }
void swap(Node& rhs)
{
using std::swap;
swap(mLeft, rhs.mLeft);
swap(mRight, rhs.mRight);
swap(mData, rhs.mData);
}
Node* left() const { return mLeft.get(); }
void left(std::auto_ptr<Node> node) { mLeft= node; }
Node* right() const { return mRight.get(); }
void right(std::auto_ptr<Node> node) { mRight = node; }
data_type& data() { return mData; }
const data_type& data() const { return mData; }
private:
std::auto_ptr<Node> mLeft;
std::auto_ptr<Node> mRight;
data_type mData;
};
<如果> C++可以防止意外问题,它会给邪恶代码打开大门。 + 1用于调试器建议,虽然我认为当函数返回时,他会发现它实际上是空的。“root”当然被删除了,但是在root -左边必须有别的东西。也许用调试器嗅探这个地址会发现一些东西…+1作为调试器的建议,尽管我认为他会发现,当函数返回时,它实际上是空的。“root”肯定被删除了,但在“root->left”处肯定还有其他东西;也许用调试器嗅探该地址会发现一些东西…为什么它在检查右节点时没有找到任何东西,但在检查左节点时却发现了一些东西?因为root只是指向垃圾内存。其他结果可能包括left only、both、note或崩溃。为什么当它检查右节点时,什么也找不到,但当它检查左节点时,却发现了什么?因为root只是指向垃圾内存。其他结果可能包括只左,两者都有,两者都没有,或者崩溃。