如何在C ++中删除BST?

时间:2017-06-01 12:04:45

标签: c++ dynamic binary-search-tree

有人可以帮我弄清楚如何正确删除我的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;
    }

2 个答案:

答案 0 :(得分:2)

很少需要做delete this,而在析构函数中它实际上是致命的。调用析构函数是因为某人已经 在对象上执行delete。通过在析构函数中执行delete this,您将获得无限递归。

此外,请勿拨打leftright析构函数,delete当然在main函数中你也不应该调用析构函数,而是使用delete。唯一一次你应该明确地调用析构函数是什么时候使用了placement new,你没有这样做。

还有一些其他缺陷,比如你永远不会检查leftright指针在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 thisdelete this很少有意义。

newT->~Tree();

你几乎不应该明确地调用析构函数。它不会释放您现在泄漏的内存。

要取消分配使用new分配的内存,必须使用delete取消分配。这也将调用析构函数,因此单独调用它将是一个错误。