2016-09-11 19 views
0

私が書いた次の関数を使ってプログラムにバイナリツリーを読み込もうとしています。コンソールのバイナリツリーをcで読み込む

void readTree(struct Dnode *root) 
{ 
    struct Dnode *temp; 
    struct Dnode *input; 
    char initData; 

    scanf(" %c",&initData); 
    input=CreateNode(initData); 

    if(initData==122){ 
     printf("Leaf\n"); 
     return; 
    } 
    else { 
     root=input; 
     temp=root; 
     printf("going to left of %c\n",initData); 
     readTree(root->lLink); 
     printf("going to right of %c\n",initData); 
     readTree(root->rLink); 
    } 
} 

メインではツリーが存在しないという点を除いて、すべてがうまくいきます。ここに私のメインプログラムがあります:

int main() 
{ 
    int n=0; 
    struct Dnode *root=NULL; 
    printf("Enter the tree as it asks. Enter z whenever there is no children :\n"); 
    readTree(root); 
    printf("%c",root->data); 
    printf("In main"); 
    return; 

} 

ツリーを入力した後に突然プログラムがクラッシュします。お手伝いください。

+1

がでていることを忘れないでくださいCの引数はvalue *で渡されます。つまり、コピーされます。これらの引数は他のローカル変数と同じように機能し、関数が返ってきたら範囲外になります。引数は失われます。 c *で参考にしてエミュレートするパスを検索してください。デバッガでコードをステップ実行するだけで2,3分を費やしただけであれば、この問題は非常に明白でした。 –

+0

あなたのプログラムはキーボード(または使用している標準の入力デバイス)から読み込みます。コンソール(またはあなたが使っている標準の出力デバイス)からではありません。 –

+0

入力?期待される出力?実際の出力? 'struct Dnode'とは何ですか? 'CreateNode'とは何ですか? – 4386427

答えて

0

を変更する必要があります。

1)あなたは機能は、ルートを変更したいが、それはメインroot

ないがstruct Dnode*で、機能はstruct Dnode*をとります。 Cは値渡しを使用するので、関数内で行われた変更は、関数が戻るときに失われることを意味します。すなわち

- 関数戻り、rootmainではまだNULLあります。そうすれば、は、NULLを逆参照しているためにクラッシュします。

代わりに、関数にはダブルポインタ(struct Dnode**)が必要です。関数内では、割り当て時に*root = ....を使用する必要があります。そして関数はreadTree(&root);のように呼び出さなければなりません

2)ノードが葉であるときは決して節を保存しません。

3)変数tempは使用されません。

4)名前root

が一緒にこれを置く再帰関数のために混乱している、あなたのコードは次のようになります。

void readTree(struct Dnode **current) // Double pointer 
{ 
    struct Dnode *input; 
    char initData; 

    scanf(" %c",&initData); 
    input=CreateNode(initData); 

    *current=input; // Save the created 

    if(initData==122){ 
     printf("Leaf\n"); 
     return; 
    } 
    else { 
     printf("going to left of %c\n",initData); 
     readTree(&((*current)->lLink)); 
     printf("going to right of %c\n",initData); 
     readTree(&((*current)->rLink)); 
    } 
} 

メインから好きそれを呼び出す:

readTree(&root); 
     ^
     notice 
+0

ありがとうございました。4386427非常に感謝しています。コードが機能しました。 –

0

引数として関数に渡される値と呼び出される関数のパラメーターは同じですが、全く異なる2つのローカル変数であることを理解する必要があります。

関数readTree()が呼び出されると、ローカル変数ルートが宣言され、値は呼び出されたときに関数に渡された値と同じ値として自動的に開始されます。 main()の変数rootとreadTree()のルートは、異なる2つの変数ですが、同じ値を持ちます。

readTree()関数では、新しいノードを作成し、返された値をreadTree()の変数rootにバインドします。私が書いたように、2つのルーツは同一ではありません。したがって、あなたの変更、バインディングはスコープ外の影響を受けません - readTree()とmain()のルートは変更されません。

この問題を処理するには、ポインタをstruct Dnodeに渡す必要があります。このよう

は、主な機能には、

struct Dnode *root; 
readTree(&root); 

とreadTreeは()もあなたのコードに問題があります

readTree(struct Dnode **root) 
+0

John Parkありがとうございました。私はそのような間違いをもう一度するつもりはない。コードが機能しました。 –

関連する問題