2017-06-01 8 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を実行すると、無限の再帰があります。

また、代わりにdeleteそれら、leftrightデストラクタを呼び出すことはありません。 もちろんmain関数では、デストラクタを呼び出すべきではありませんが、deleteを使用してください。デストラクタを明示的に呼び出す必要があるのは、新しい配置を使用したときだけです。 leftまたはrightポインタがPrint機能にNULLポインタがある場合、あなたは決してチェックしないように

は、同様に他のいくつかの欠陥があります。

最後に、thisがヌルポインタの場合は、深刻な問題がありますので、確認する必要はありません。あなたが全体のサブツリーが自動的に削除されますmain機能でdelete newTを行う場合


デストラクタは単純

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

でなければなりません。

+0

私は理解しますが、代わりにメモリを解放する必要がありますか?最初にnewTというオブジェクトを削除しただけでは、その子にアクセスすることはできません。 – Valio

+0

@ValentinKostadinov木を削除すると、なぜ子供たちにアクセスしたいのですか? –

+0

気にしないでください。みんなありがとう。私はそれを得て、そのような間違いを避けようとします。 – Valio

0

C++でBSTを削除するにはどうすればよいですか?

空子供がヌルではなく、センチネルオブジェクトを指すと仮定し、ノードを仮定をnewが割り当てられた、ノードのデストラクタは、単に両方の子を削除することによって実現することができる。

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

if(this == NULL) 

これはほとんど意味がありません。メンバー関数は、NULLポインター上で呼び出すことはできません。デストラクタ内

delete this; 

あなたはできませんdelete thisdelete thisにはほとんど意味がありません。

newT->~Tree(); 

あなたはめったに明示的にデストラクタを呼び出す必要があります。それはあなたが今漏れているメモリの割り当てを解除しません。

newで割り当てたメモリの割り当てを解除するには、deleteで割り当てを解除する必要があります。これはデストラクタも呼び出すので、別々に呼び出すと間違いになります。

関連する問題