2012-02-28 10 views
-2

このプログラムは、バイナリツリーノードの挿入、削除を行う必要があります。 問題は、削除後にツリー要素を表示すると、プログラムにエラーが表示されることです。私のプログラムで何が間違っているのを助けてください。誰でもこのプログラムの何が間違っているか知っていますか?

#include <iostream.h> 
#include <stdlib.h> 
#include <string> 

class Tnode 
{ 
public: 
    class Tnode *left; 
    class Tnode *right; 
    int info; 
}; 

class tree: public Tnode 
{ 
public: 
    int top; 
    Tnode *root; 

    tree() 
    { 
     root=NULL; 
     top=0; 
    } 

    void insert(int ch) 
    { 
     Tnode *temp,*temp1; 
     if(root== NULL) 
     { 
      root=new Tnode; 
      root->info=ch; 
      root->left=NULL; 
      root->right=NULL; 
      return; 
     } 
     temp1=new Tnode; 
     temp1->info=ch; 
     temp1->right=temp1->left=NULL; 
     temp=search(root,ch); 
     if(temp->info>ch) 
      temp->left=temp1; 
     else 
      temp->right=temp1; 
    } 

    Tnode *search(Tnode *temp,int ch) 
    { 
     if(root== NULL) 
     { 
      cout <<"no node present"; 
      return NULL; 
     } 
     if(temp->left==NULL && temp->right== NULL) 
      return temp; 

     if(temp->info>ch) 
     { 
      if(temp->left==NULL) return temp; 
      search(temp->left,ch); 
     } 
     else 
     { 
      if(temp->right==NULL) return temp; 
      search(temp->right,ch); 
     } 
    } 

    void display(Tnode *temp) 
    { 
     if(temp==NULL) 
      return; 

     display(temp->left); 
     cout<<temp->info; 
     display(temp->right); 
    } 

    Tnode *getposition(Tnode *root, int x) 
    { 
     Tnode *temp; 
     temp=root; 
     while(temp&&temp->info != x) 
      ((temp->info>x)?(temp=temp->left):(temp=temp->right)); 
     return(temp); 
    } 

    Tnode *getleft_right_most(Tnode *temp) 
    { 
     Tnode *m=temp->left; 
     while(temp->right) 
      temp=temp->right; 
      return temp; 
    } 

    Tnode *getfather(Tnode *root, Tnode *temp) 
    { 
     Tnode *h=root; 
     while(h->left!=temp&&h->right!=temp) 
      ((h->info>temp->info)?h=h->left : h=h->right); 
     return h; 
    } 

    Tnode *del(Tnode *temp, Tnode *f) 
    { 
     if(temp->left&&temp->right) 
     if(temp->right) 
     { 
      (f->left==temp)?f->left=temp->right : f->left=temp->right; 
      temp->right=0; 
     } 
     if(temp->left) 
     { 
      (f->right==temp)?f->right=temp->left : f->right=temp->right; 
      temp->left=0; 
     } 

     free(temp); 
    } 

    Tnode *delroot(Tnode *root) 
    { 
     Tnode *d=root; 
     if((d->right)&&!(d->left)) 
     { 
      root=d->right; 
      d->right=0; 
     } 
     else if((d->left)&&!(d->right)) 
     { 
      root=d->left; 
      d->left=0; 
     } 
     else 
      root=0; 
     return d; 
    } 

    Tnode *delprocess(Tnode *root, int key) 
    { 
     Tnode *d=root; 
     Tnode *temp,*f,*t,*Re; 
     if(root->info==key) 
     { 
      Re=delroot(d); 
      return(Re); 
     } 
     else 
     { 
      temp=getposition(d,key); 
      if(temp->left!=0&&temp->right!=0) 
      { 
       t=getleft_right_most(temp); 
       temp->info=t->info; 
       temp=t; 
      } 

      f=getfather(d,temp); 
      Re=del(temp,f); 
      return(Re); 
     } 
    } 
}; 

main() 
{ 
    tree t1; 

    int ch,n,i; 
    while(1) 
    { 
     cout <<"\n1.INSERT\n2.DELETE NUMBER\n3.DISPLAY\n4.EXIT\nEnter your          choice:"; 
     cin >> ch; 
     switch(ch) 
     { 
     case 1: do{ 
       cout <<"\nenter the elements you want to insert:"; 
        cin >> ch; 
       cout<<"\nto exit insert the number -1."; 
         if(ch!=-1) 
         t1.insert(ch); 
         }while(ch!=-1); 
         break; 
     case 2: t1.display(t1.root);break; 
     case 3: cout<<"\nto delete a number of your insertion enter it : "; 
        cin>>n; 
       t1.root=t1.delprocess(t1.root,n); 
       cout<<"\nthe tree after deletion is : "; 
       t1.display(t1.root); break; 
     case 4: exit(1); 
     } 
    } 
} 
+3

...おそらくもっとありますが、エラーを示して?それはすべてあなたが言うことができるのですか?私は同様の方法で答えることができます:あなたのプログラムに何が問題なのですか?よく、それはバグがあります... –

答えて

2

<iostream.h>はありません。 <iostream>を使用する必要があります。 <stdlib.h><cstdlib>に置き換えてください。

さらに、coutcinを使用しています。どちらもネームスペースstdに定義されています。ですので、ファイルの先頭にstd::coutまたはusing namespace std;を使用してください。後者はお勧めしません。

したがって、次のものを使用して最初の3行を交換し、あなたのプログラムがコンパイルされます:あなたのコードをコンパイルは問題がありませんでしたし、場合

#include <iostream> 
#include <cstdlib> 
#include <string> 

using namespace std; 

しかし、あなたのエラーは完全に異なる何かがあなたが追加する必要がありますのではなく、あなたの質問に具体的なエラーメッセージが表示されます。

0

あなたには小さなバグはありません。あなたはあまりにも多くのことが間違っています。私はあなたがデバッガでIDEを取得し、何が起こっているかを確認するコードをステップすることをお勧めします。あなたは再帰的に検索呼び出しができますが、返された値を使用することを忘れTnode *searchに例えば

、:

//    search(temp->left,ch); 
       return search(temp->left,ch); 
//    ^^^^^^ 
//    search(temp->right,ch); 
       return search(temp->left,ch); 
//    ^^^^^^ 

もう一つは、1:Tnode *getleft_right_mostに、あなたはおそらく、この代わりにしたい:

Tnode *m=temp->left; 
// while(temp->right) 
//  temp=temp->right; 
//  return temp; 
    while(m->right) 
     m=m->right; 
     return m; 

これは、あなたのコンパイラがあなたを助けることができるもの。 -Wallを使用するか(またはすべての警告を有効にする)、変数mを作成し、使用するのを忘れたことを指摘します。 、Tnode *delroot

if(temp->left&&temp->right) { 
    if(temp->right) 
    { // ... 
    } 
} 

:コンパイラはちょうど文の場合は、2番目を取り、行方不明体として使用します

if(temp->left&&temp->right) 
if(temp->right) 

Tnode *delでは、本体なしif記載がありますおそらく

return root; 

ではなく、return dです。 rootがleftrightの両方の枝を持っている場合も扱いません。

その他では、残りのバグはあなたのための練習です。

オプション2と3を交換したことは言及したくありませんでしたが、それはかなり面倒でした。

最後のヒント:rootメンバーを持つtreeクラスを作成したので、メンバー関数の引数としてrootを渡す必要はありません。

2

これで間違ってはかなりあります:

  1. #include <iostream.h>ニーズが#include <iostream>
  2. main()ことがint main()する必要があります。
  3. tree::delは値を返す必要があります。
  4. main()のスイッチのケースが、スイッチの上のメッセージの出力と一致しません。
  5. コントロールが最後のif elseブロックに渡された場合、値を返しません。
  6. を使用してTnodeが割り当てられているため、の代わりにdeleteを使用して割り当て解除する必要があります。
  7. 生のスマートポインタを優先します。 Tnode*std::shared_ptr<Tnode>となり、電話を避けることができますdelete
  8. treeTnodeから継承する必要はありません。
  9. Tnodeは、パブリックメンバーのみで機能はないため、structである必要があります。
  10. 意味のある変数名は
  11. は一般クラスは、パブリックメンバ変数を持つパブリックアクセサを持つクラスのデータはプライベートにするべきではありません(例えば、父のために短いfある?)の理解を助けます。
  12. コンストラクタ本体の代入ではなく、初期化リストのクラスメンバーを初期化することをお薦めします。
  13. 一貫性があります。例えばNULLまたは0のいずれかを使用してください。両方ともではありません(C++ 11コンパイラでは、確かにnullptrに固執します)。
  14. メンバ関数のパラメータからクラスメンバ変数を曖昧さをなくします。どちらの場合もrootを使用してください。
  15. アライメントと書式設定には注意してください。コントロールブロックがそれよりも大きくなることをアライメントが意味する場所がいくつかあります。書式の一般的な状態は、(この場合、非常に正確に)注意の不足を即座に感知し、読者にロジックを即座に疑わせるものでなければなりません。

そして

+0

+1、特に\ [15 \]:私はちょうどOPのコードを少しきれいにしようとしました。私は20番目のミスアライメント後にあきらめました... – Zeta