2017-06-01 33 views
0

有人可以幫我弄清楚如何正確刪除我的bst實現嗎?我知道這是一個簡單的問題,但我嘗試了一切。我想避免聲明一個動態數組,並且如果可以用這個指針結構保持代碼(不是雙關語意圖)。問題在於析構函數部分。謝謝 !如何刪除C++中的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

有很少有任何需要做delete this,並在析構函數,它實際上是致命。被調用的析構函數是因爲某人已經在對象上執行delete。通過在析構函數中執行delete this,您可以進行無限遞歸。

此外,請勿調用leftright析構函數,delete來代替它們。 當然在main函數中,你不應該調用析構函數,但使用delete。唯一一次你應該明確地調用析構函數的時候是使用了放置新的,你還沒有做過。

還有一些其他缺陷,例如,您從不檢查leftright指針是否爲Print函數中的空指針。

最後,如果this是一個空指針,那麼你在其他地方有一些嚴重的問題,所以從來沒有任何需要檢查它。


析構函數應該簡單地

~Tree() 
{ 
    delete left; 
    delete right; 
} 

如果你再在main功能全子樹將被自動刪除做delete newT

+0

我明白了,但我該如何釋放內存呢?如果我只是首先刪除對象newT,那麼我將無法訪問其子項。 – Valio

+0

@ValentinKostadinov爲什麼你想要訪問孩子,如果你刪除樹? –

+0

沒關係。多謝你們。我明白了,並會盡量避免這樣的錯誤。 – Valio

0

如何在C++中刪除BST?

Tree::~Tree() { 
    delete left; 
    delete right; 
} 

假設空孩子點爲空,而不是一個定點對象並假設節點用new分配,一個節點的析構函數可以通過簡單地刪除兩個孩子來實現

if(this == NULL) 

這沒什麼意義。成員函數不能在空指針上調用。

delete this; 

你不能delete this析構函數中。這對delete this很有意義。

newT->~Tree(); 

你很少應該顯式調用析構函數。它不會釋放您現在泄漏的內存。

要取消分配您用new分配的內存,必須用delete釋放內存。這也會調用析構函數,所以單獨調用它會是一個錯誤。