有人可以帮我弄清楚如何正确删除我的bst实现吗?我知道这是一个简单的问题,但我尝试了一切。我想避免声明一个动态数组,如果有可能保持代码与这个指针结构(没有双关语)。问题在于析构函数部分。谢谢!
#include<iostream>
using namespace std;
struct Tree{
struct Tree* left;
struct Tree* right;
int val;
Tree(int);
~Tree();
void Print();
};
Tree::Tree(int val){
this->val = val;
cout<<"insert l/r for node: "<<this->val<<" , type 0 0 - exit" <<endl;
int l,r;
cin>>l>>r;
if(l and r){
this->left = new Tree(l);
this->right = new Tree(r);
}else if(l==0 and r==0){
this->left = NULL;
this->right = NULL;
return;
}
}
Tree::~Tree(){
if(this->left == NULL and this->right == NULL){
delete this;
return;
}else{
this->left->~Tree();
this->right->~Tree();
}
}
void Tree::Print(){
if(this == NULL) return;
cout<<this->val<<endl;
this->left->Print();
this->right->Print();
}
int main(){
int n;
cin>>n;
Tree* newT = new Tree(n);
newT->Print();
newT->~Tree();
//cout<<newT->val<<endl;
//newT->Print();
return 0;
}
答案 0 :(得分:2)
很少需要做delete this
,而在析构函数中它实际上是致命的。调用析构函数是因为某人已经 在对象上执行delete
。通过在析构函数中执行delete this
,您将获得无限递归。
此外,请勿拨打left
和right
析构函数,delete
。 和当然在main
函数中你也不应该调用析构函数,而是使用delete
。唯一一次你应该明确地调用析构函数是什么时候使用了placement new,你没有这样做。
还有一些其他缺陷,比如你永远不会检查left
或right
指针在Print
函数中是否为空指针。
最后,如果this
是一个空指针,那么你在其他地方遇到了一些严重的问题,所以永远不需要检查它。
析构函数应该只是
~Tree()
{
delete left;
delete right;
}
如果您在delete newT
函数中执行main
,则会自动删除整个子树。
答案 1 :(得分:0)
如何在C ++中删除BST?
假设空子节点指向null而不是sentinel对象,并假设节点分配了new
,则可以通过简单地删除两个子节点来实现节点的析构函数:
Tree::~Tree() {
delete left;
delete right;
}
if(this == NULL)
这没什么意义。不能在空指针上调用成员函数。
delete this;
析构函数中不能delete this
。 delete this
很少有意义。
newT->~Tree();
你几乎不应该明确地调用析构函数。它不会释放您现在泄漏的内存。
要取消分配使用new
分配的内存,必须使用delete
取消分配。这也将调用析构函数,因此单独调用它将是一个错误。