2016-11-01 10 views
0

ここで私はバイナリ検索ツリーを実装しようとしています。グローバルコンテキストでルートノードを宣言しました。私はリンクリストを実装したのと同じアイデアをたどりました。しかし、 .Iは、誰も私がpush()私のBSTに要素が挿入されない理由

#include<stdio.h> 
struct node { 

    int data; 
    struct node *left; 
    struct node *right; 
}; 
void insert(int value); 
void push(struct node *temp,struct node *newNode); 


struct node *root; 
int main(){ 
    root= NULL; 
    int option,value; 
    for(;;){ 
     printf("Please select an option from below : \n"); 
     printf("1 for insert\n"); 
     printf("2 for search\n"); 
     printf("please enter your option : "); 
     scanf("%d",&option); 
     printf("\n"); 
     switch(option){ 
      case 1: 
       printf("you choose to insert\n"); 
       printf("input your value :"); 
       scanf("%d",&value); 
       insert(value); 
       printf("\n"); 
       break; 
      case 2: 
       printf("You choose to search\n"); 
       printf("enter your value : "); 
       scanf("%d",&value); 
       search(root,value); 
       printf("\n"); 
      default: 
       break; 

     } 
    } 
} 

void insert(int value){ 
    struct node *newNode = (struct node *)malloc(sizeof(struct node)); 

    newNode->data = value; 
    newNode->left = NULL; 
    newNode->right = NULL; 


    push(root,newNode); 

} 
void push(struct node *root_node,struct node *newNode){ 

    if(root_node==NULL){ 
     root_node = newNode; 
     printf("inserted\n\n\n"); 
    }else{ 
     if(root_node->data > newNode->data){ 
       push(root_node->left,newNode); 
       printf("left\n"); 
     }else{ 
      push(root_node->right,newNode); 
      printf("right\n"); 
     } 

    } 

} 
+2

'push()'では、 'root_node = newNode;'は呼び出しコードに影響を与えないので、目的を果たしません。この上に多くの愚か者。おそらく[この1つ](http://stackoverflow.com/questions/20172603/why-do-we-need-to-return-the-head-pointer-in-a-bst-after-inserting-node)? – chux

+0

あなたは少し説明してくださいできます..私はまだ混乱しています! –

+0

C *で参照渡しを*エミュレートすることについて検索して読んでください。 –

答えて

3

これを見つけ出す手助けこのcode.Canで間違っているものを理解できない、root_nodeにはローカル変数です:

void push(struct node *root_node,struct node *newNode){ 

あなたが行うと:

あなたのプッシュ()のようなものでなければなりません

struct node *root; 

void push(struct node **root_node,struct node *newNode){ 
    if(*root_node==NULL){ 
     *root_node = newNode; 
     printf("inserted\n\n\n"); 
    }else{ 
... 

およびコール:

あなただけのローカル変数 "root_nodeに" ではなく、グローバルを更新している
root_node = newNode; 

push(&root, newNode); 

このようにして、rootのアドレスを渡し、あなたの内部でそれが指し示しているかどうかを確認しますアドレスはNULLです。 nullの場合は、newNodeのアドレスをポインタdereferencedに代入します。

詳細な説明:

struct node *rootポインタです:タイプだ変数は、「ポインタ/アドレス」です。そして、データを記憶しているブロックを指して、「A」と呼ぶことにしましょう。

struct node *root_nodeは、ローカル変数として、それがポイントに「A」データのメモリ内に、そしてあなたの場合のブロックへのポイントは(あなたが「ルート」を渡すため)こと、COPYで、ポインタです。

root_nodeを変更すると、コピーrootに変更されません。あなたがやっていることは、 "A"を変更するためだけに使用することができます。

あなたがアドレスルートのを渡すために持っているので、あなたは実際には「A」へのポインタがあるルートの値を、変更することができます。そうすれば、** root_nodeはrootへのポインタで、ACTUAL rootは "A"を指していて、他の場所を指し示すことができます。

私はあなたのソリューションが間違っている理由を示すために画像をアップロードする:

enter image description here

あなたが見ることができるように、rootが更新決してです。

(P .:ポインタが変数である変数なので、ポインタをコピーすることができます。ポインタは*variableで逆参照します)。

+0

あなたのプッシュ関数では(* root_node == NULL)ここに... * root_nodeは&root ....のアドレスを意味しますか?アドレスはnullにはなりません。最初のノードを挿入する方法は? –

+0

いいえ、 'root_node'は'&root'(ルートのアドレス)で、 '* root_node'は' root'です。あなたはhttps://en.wikipedia.org/wiki/Dereference_operatorのリンクを読んでいましたか?間接参照の図は次のとおりです。http://images.slideplayer.com/19/5772771/slides/slide_38.jpgこれを理解しようとしましょう:私があなたの変数、ヒープ、そしてスタックに入ったらスタックを押してください。それぞれが何であるか、どこにポイントがあるのでしょうか?) –

+0

コメントするのを忘れてしまいました。私のpush()関数では、ノードのデータにアクセスするために '(*(* root_node))data'を実行できます:)。 '(* variable).field'は' variable-> field'と書くことができる構文的な砂糖のヒントを覚えているので、 '(*(* root_node))。data'を'(* root_node) - > data'と書くことができます –

0

次の行は、グローバル変数rootを更新するNOTです。

push(root,newNode); 

} 
void push(struct node *root_node,struct node *newNode){ 

    if(root_node==NULL){ 
     root_node = newNode; 
     printf("inserted\n\n\n"); 

あなたはrootがグローバルになりたいので、一つの選択肢は、グローバルrootが使用されるように、次のようにこれを変更することです。

push(newNode); 

} 
void push(struct node *newNode){ 

    if(root == NULL){ 
     root = newNode; 
     printf("inserted\n\n\n"); 

などとなる。 (注:これは完全な解決策ではありません)

+0

struct node * root_nodeはルートノード自体へのポインタです。なぜそれを更新しないのですか?あなたの2番目の例の –

+0

私がroot_nodeパラメータを省略すると再帰呼び出しをどのように処理できますか? –

+0

'root_node'はローカル変数なので、' root_node'への更新は 'root'に反映されません。 – Arun

関連する問題