2016-04-10 17 views
1

私の挿入機能は正しいと思いますが、新しいノードがツリーに挿入されていないようです。私は間違いがどこにあるのか分からなかった。私は助けていただきありがとうございます。新しいノードをバイナリツリーに挿入できません

ノードやツリーの宣言があります:

class Node{ 
    int key; 
    Node *right, *left; 
} 

class Tree{ 
public: 
     int init(); 
     Node *root; 
     Node *insert(int key, Node *p); 
}; 

機能があります:

int Tree::init(){ 
    this->root = NULL; return 1; 
} 

Node *Tree::insert(int key, Node *p){ 
    if(p == NULL){ 
    Node *novo = new Node(); 
    novo->key = key; 
    novo->left = NULL; 
    novo->right = NULL; 
    p = novo; 
    } 
    else if(key < p->key){ p->left = insert(key, p->left); } 
    else if(key > p->key){ p->right = insert(key, p->right); } 
    else{ cout << "Error: key already exist" << endl; } 

return p; 
} 

私がメインで関数を呼び出すと、それは新しいをリンクしないように、それは見えますが、ノード

int main() { 
    Tree dictionary; 

    cout << "enter the key"; cin >> key; 

    dictionary.insert(key, dictionary.root); 

    cout << dictionary.root->key; 
} 
+0

トピックオフ:なぜ 'int Tree :: init()'の代わりにコンストラクタ? – user4581301

+0

あなたの 'MCVE'はコンパイルされません - 私は' gcc'でそれを試しました。 –

答えて

1

insert()関数では、ツリーが空の場合、または最後のノードに到達した場合、crea新しいノードをTEは

if(p == NULL){ 
    Node *novo = new Node(); 
    novo->key = key; 
    novo->left = NULL; 
    novo->right = NULL; 
    p = novo;    // ouch !!!! 
    } 

残念ながら、声明p=novoは、あなたの関数のローカルパラメータpを更新します。その値は、関数から戻るとすぐに消えます。関数を呼び出したポインタは更新されません。したがって、ツリーのルートはNULL(または最後のノードの左/右ポインタ)のままです。

Node *insert(int key, Node *& p); // p is passed by reference 

この意志:

は、あなたが期待する効果を得るには、あなたが署名を変更する必要があります(つまり、あなたの p assigmentは、ルートポインタまたは最後のノードの/右を左にポインタを更新します)参照によってポインタ pを渡してください。 pを変更すると、関数の呼び出しに使用したポインタが変更され、挿入の効果が持続します。

+0

あなたは 'main'に初期化されていない変数' dictionary.root'を渡していると言及していることを忘れてしまいました。 –

+0

ありがとうChristophe !!!これは一生懸命練習したものですが、私はこの詳細に気づくことができませんでした –

+0

@AlBundyはい、OPはinit()を忘れていたからです。 init()の代わりにコンストラクタを作ると、この種の厄介なバグを避けることができます;-) – Christophe

関連する問題