2017-10-18 22 views
0

CでBinary Serach Treeを実装しようとしています。このコードでは、ツリーに値を追加してその値がツリーにあるかどうかを確認しようとしました。しかし、私の試みたコードは常にtrueを返します。バイナリ検索ツリーで値が正しく認識されない

何度もチェックしました。私はまだCプログラミングを学んでいます。

ここに私のコードです。

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
typedef struct BSTnode { 
    int data; 
    struct BSTnode *left; 
    struct BSTnode *right; 
    } BSTnode; 

BSTnode *getNewNode(int data){ 
    BSTnode *newNode = (BSTnode*)malloc(sizeof(BSTnode)); 
    newNode->data=data; 
    newNode->left=newNode->right=NULL; 
    } 
BSTnode* InsertNew(BSTnode *root,int data){ 
    if(root == NULL){ 
     root = getNewNode(data); 
       } 
     else if(data <= root->data){ 
      root->left = InsertNew(root->left,data); 
      } else{ 
       root->right = InsertNew(root->right,data); 
       } 
     return root; 
     } 

bool search(BSTnode *root, int data){ 
    if(root== NULL) return false; 
    else if(root->data == data) return true; 
    else if (data <= root->data) return search(root->left,data); 
    else return search(root->right,data); 

    } 
int main() 
{ 
//node to store root 

BSTnode *root = NULL; 

root = InsertNew(root,34); 
root = InsertNew(root,4); 
root = InsertNew(root,3); 
root = InsertNew(root,1); 

int num; 
printf("enter a number : \n"); 
num =scanf("%d"); 

if(search(root,num)==true){ 
    printf("found"); 
    }else{ 
    printf("not found"); 
    } 
    return 0; 
} 

私はここで何が欠けていますか?

ありがとうございます。

+2

まだお持ちでない場合は、*デバッガ*の使用方法と、プログラムをデバッグするための使い方を学ぶのに最適な時期です。 Eric Lippertによる[小さなプログラムのデバッグ方法](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を読んでみてください。 –

+2

また、で警告を出してコンパイルしてください。たとえば、新しいノードを返す必要があるときは、 'getNewNode'から何も返しません。 –

+0

コードのインデントを修正するようにしてください。これは、あなたとあなたのコードの今後の読者の両方に役立ちます。 –

答えて

5

あなたは

num =scanf("%d"); 

は、あなたはそれが(scanf関数が正常にEOFに変換または-1アイテムの数を返します)んだと思う何をしていないことを表示されません。あなたが返すように起こる)(あなたが壊れたプログラムで

if (scanf ("%d", &num) != 1) { 
    /* complain */ 
} 

が必要なことを教えてくれのに十分高い、scanf関数をコンパイラの警告レベルをクランクなかった1(それは1つのアイテムを変換してランダムメモリにそれを書いたので)とツリーに1があるので、あなたは常に真実になります。

+0

私にそれを指摘してくれてありがとう。 – Sachith

3

@ Jensによって指摘されたエラーに加えて、getNewNodeから値を戻していません。明細書を追加します。

return newNode; 

最後にその機能を追加します。それはしかし持って何も返さないので、ここではパラメータなし機能main

int main(void) 

機能getNewNode

BSTnode *getNewNode(int data){ 
    BSTnode *newNode = (BSTnode*)malloc(sizeof(BSTnode)); 
    newNode->data=data; 
    newNode->left=newNode->right=NULL; 
    } 

のように宣言されなければならないC規格に従って手始めにfixed example on ideone

+0

'scanf("%d "、&num);'を回答に追加してください。 'return newNode;を修正した後にも問題があったので、 – Sachith

+0

私は@ Jensによって指摘されたエラーに加えて私はこれが問題だと思っていますが、そのエラーは私には見られませんでした.Jensの答えはそれについて十分な詳細を示しています。 –

3

があることは未定義の動作をしています戻り値の型はBSTnode *です。

関数は、関数InsertNewがwrong.Takeバイナリ検索ツリーのための通常の代わりにオペレータ<=オペレータ<が使用されることが考慮され、以下のよう

BSTnode * getNewNode(int data) 
{ 
    BSTnode *newNode = (BSTnode *)malloc(sizeof(BSTnode)); 

    if (newNode != NULL) 
    { 
     newNode->data = data; 
     newNode->left = newNode->right = NULL; 
    } 

    return newNode; 
} 

を定義することができます。

これらのステートメント

root->left = InsertNew(root->left,data); 

root->right = InsertNew(root->right,data); 

は意味をなさないとroot->leftと実際に変更してはならないノードのroot->rightの値を上書きしません。また、作成されたノードはNULLに等しいことができ、この場合元のルートノードもNULLで上書きされます。

参照元のルートノードをポインタで渡す方が適切です。

また、operator <=の代わりにoperator <を使用する必要があります。

関数の定義は次のよう

BSTnode * InsertNew(BSTnode **root,int data) 
{ 
    if (*root == NULL) 
    { 
     *root = getNewNode(data); 
     return *root; 
    } 
    else if (data < (*root)->data) 
    { 
     return InsertNew(&(*root->left), data); 
    } 
    else 
    { 
     return InsertNew(&(*root->right), data); 
    } 
} 

を見ることができる機能は、ルートノードへの復帰ポインタを割り当てず

InsertNew(&root, 34); 

ように呼ぶことができます。戻り値は、必要であればifステートメントで調べることができます。

ツリーで重複する値を持ってしたくない場合は、関数は

BSTnode * InsertNew(BSTnode **root,int data) 
{ 
    if (*root == NULL) 
    { 
     *root = getNewNode(data); 
     return *root; 
    } 
    else if (data < (*root)->data) 
    { 
     return InsertNew(&(*root->left), data); 
    } 
    else if ((*root)->data < data) 
    { 
     return InsertNew(&(*root->right), data); 
    } 
    else 
    { 
     return NULL; 
    } 
} 

それに対応して機能searchがで使用して

bool search(BSTnode *root, int data) 
{ 
    if (root == NULL) 
    { 
     return false; 
    } 
    else if (data < root->data) 
    { 
     return search(root->left, data); 
    } 
    else if (root->data < data) 
    { 
     return search(root->right, data); 
    } 
    else 
    { 
     return true; 
    } 
} 

のように定義されるべき次のように書くことができますこの明細書の機能scanf

num =scanf("%d"); 

が間違っています。

正しい呼び出しはif文

if (scanf("%d", &num) == 1) 
{ 
    //... 
} 

に条件を使用してます。また、呼び出しが成功したかどうかを確認することができます

printf("enter a number : "); 
scanf("%d", &num); 

のようになります。そして、あなたがのために割り当てられたすべてのメモリを解放する必要がありますツリーを開き、プログラムを終了します。

一般的には、関数は、の場合には、そのように書き換えされる場合ため代わり真

if(search(root,num)==true){ 

との厳密な比較を以下の条件

if(search(root,num)){ 

を使用する方がよいです成功すると0以外の値が返され、trueとの厳密な比較は機能しません。

関連する問題