2017-06-10 22 views
1

私はクラスを使用してバイナリ検索ツリーを実装しようとしています。プログラムをコンパイルして実行しようとするたびに、プログラムは終了します。私は*ルートをパブリックにしてメインにアクセスするようにしました。ルートを更新することができますが、何とか毎回nullになります。 ヘルプをいただければ幸いです。 私の大学のプロジェクトです。 rootは何度も何度もNULLを取得し、なぜクラスを使用したバイナリ検索ツリー

#include <iostream> 
using namespace std; 
class tree; 
class Node { 
    friend class tree; 
private: 
    Node *lchild,*rchild; 
    int data; 
public: 
    Node (int x) { 
     data = x; 
     lchild = rchild = NULL; 
    } 
}; 
class tree { 
protected: 
    Node* root; 
    void inorder(const Node* root)const; 
public: 
    tree() { 
     root = NULL; 
    } 
    bool insert(int item); 
    void inorder() const {inorder(root);}; 
    Node* getroot() { 
     return root; 
    } 
}; 
bool tree :: insert(int item) { 
    if (root == NULL) { 
     Node *temp = new Node(item); 
     root = temp; 
     return (bool) root; 
    } 
    if (item < root -> data) { 
     insert(item); 
    } 
    if (item > root -> data) { 
     insert(item); 
    } 
    else if (item == root -> data) { 
     cout<<"Duplicate"; 
     exit (0); 
    } 
    return (bool) root; 
} 
void tree :: inorder(const Node *root)const { 
    if (root != NULL) { 
     inorder(root -> lchild); 
     cout<<root -> data; 
     inorder(root -> rchild); 
    } 
} 
int main() 
{ 
    tree obj1; 
    obj1.insert(3); 
    //obj1.insert(4); 
    obj1.insert(1); 
    //obj1.insert(5); 
    obj1.inorder(); 
} 
+0

なぜtree :: insertにルートパラメータがありますか? –

+0

なぜあなたは 'root1'と' root'を同時に持ち、別々のことをしていますか? –

+0

@ manni66私はそれをCからC++に変換していたので、やってみましたが、再帰で役立つと思いました。 –

答えて

0

理由は、それが実際にNULL以外のものにその値を変更しないことです。 他の問題を修正する際に、この動作をコードに導入したことがあります。コンストラクタにはroot=NULLを割り当てます。後でobj.root1 = ...を割り当て、にはrootを返します。さらに、関数内にパラメータとしてNode *rootを渡します。 rootという名前のこのローカル変数は、データメンバrootを非表示にします。したがって、これらの関数のroot->...は、常にデータメンバではなくローカル変数に対処します。

インターフェイスのデザインを変更する前に、デザインを変更してからコードを修正することをお勧めします。私は間違いが単に消え去るだろうと確信しています。私はclass treeのインターフェイスを次のように適合させ、そのコードを書き込むことを提案します。

メンバー機能inorder()は、オブジェクトの状態を変更しないことを示すためにconstである必要があります。 const-member関数は、他の非静的メンバー関数とは対照的に、const -objectsで呼び出すことができます。

class Node { 
    friend class tree; 
private: 
    Node *lchild,*rchild; 
    int data; 
public: 
    Node (int x) { 
     data = x; 
     lchild = rchild = NULL; 
    } 
}; 
class tree { 
public: 
    tree() { root = NULL; } 
    bool insert(int item) { return insert(item,root); }; 
    void inorder() const { inorder(root);}; 

protected: 
    Node* root; 
    void inorder(const Node* curr) const; 
    bool insert(int item, Node* curr); 

}; 

bool tree :: insert(int item, Node *currNode) { 
    if (root == NULL) { 
     root = new Node(item); 
     return true; 
    } 
    else if (item < currNode->data) { 
     if (currNode->lchild == NULL) { 
      currNode->lchild = new Node(item); 
      return true; 
     } 
     else { 
      return insert(item, currNode->lchild); 
     } 
    } 
    else if (item > currNode->data) { 
     if (currNode->rchild == NULL) { 
      currNode->rchild = new Node(item); 
      return true; 
     } 
     else { 
      return insert(item, currNode->rchild); 
     } 
    } 
    else // item == currNode->data 
     return false; // duplicate; do not insert 
} 
+0

@Stephenを提供します。関数の後にconstを使用する理由は何ですか? –

+0

@ Kanishka Kapoor:答えに理由を追加しました。それが助けてくれることを願って:-) –

+0

@Stephenありがとう!しかし、私の大学のように** inorder関数**を再帰的に呼び出すように教えられました!だから私は出力のためにしようとしているときに、私は本当にこの周りに私の頭を得ることはできません! –

関連する問題