我还在处理我的二叉树,插入,查找,最大,最小功能到目前为止都很好用。所以我想接下来做一个删除功能。我加入了一个可以保存的堆栈 - 啊,我只会显示代码:
class Tree
{
private:
int value_;
Tree *root_;
Tree *left_;
Tree *right_;
std::stack<Tree*> treeStack;
删除功能:
int Tree::eraseTree()
{
while( !treeStack.empty() )
{
Tree *temp = treeStack.top();
treeStack.pop();
delete temp;
}
if( treeStack.empty() )
return 1;
else
return -1;
}
我现在收到错误。这不是什么大问题 - 我尝试调试自己的代码 - 除了这次它告诉我<deque>
库文件中有一个我甚至不使用的错误。
在程序关闭之前,我得到System.AccessViolationException
,错误的代码指向deque
文件。当然它不能存在,它必须是我的代码中的一些指针。这让我相信我没有正确地处理堆栈,或者没有正确地推送到堆栈。
我在这里做错了什么?当我在堆栈上调用.pop时,我实际上是在删除节点吗?
修改
if( !root_ )
{
root_ = new Tree(val, 0, 0);
treeStack.push(root_);
return val;
}
和
Tree *parent = findInsertionPoint(val, root_);
if( val < parent->value_ )
parent->left_ = new Tree(val, 0, 0);
else
parent->right_ = new Tree(val, 0,0);
treeStack.push(parent);
return val;
我在堆栈上推送元素的位置。
附加问题:是否必须在ctor中构建std :: stack?
答案 0 :(得分:2)
将root_*
,left_*
和right_*
更改为auto_ptrs以确保其销毁。然后当你来删除一个节点时,你可以删除root_.release();一切都很好。要问你为什么要使用堆栈。
答案 1 :(得分:2)
你在deque
崩溃,因为堆栈包含其中一个。如果你在崩溃后查看堆栈跟踪,那么你可以找到你的代码在发生时所做的事情。
看起来最后一段代码是将错误的节点放在堆栈上;当然它应该是新创建的节点,而不是插入点?如果将两个节点添加到父节点,则父节点将最终在堆栈中两次,并将被删除两次。
应该更像是
Tree *parent = findInsertionPoint(val, root_);
Tree *child = new Tree(val, 0, 0);
if( val < parent->value_ )
parent->left_ = child;
else
parent->right_ = child;
treeStack.push(child);
return val;
但我赞成DeadMGs建议使用left_
和right_
的智能指针(但不要使root_
成为auto_ptr
,如果所有人共享的话节点),让他们为你清理。我不确定我是否看到了筹码的重点;如果是为了加速树的破坏,那么在添加复杂且容易出错的优化之前,先问自己两个问题:
您的其他问题:stack
将在构造函数中构建,但您不必编写任何代码来执行此操作。它的默认构造函数将被自动调用,这将为您提供一个可用的空栈。
此外,除非这是一个学习练习,否则你应该使用std::multiset
而不是重新发明它。
答案 2 :(得分:1)
听起来你可能会删除两次。
确保您正在删除的内容未在其他任何地方使用或删除,尤其是在调用eraseTree()方法之后。
答案 3 :(得分:1)
deque 中出现错误,因为默认情况下std :: stack将此类用作内部容器。查看堆栈定义:
template<class _Ty, class _Container = deque<_Ty> > class stack;