0

私は次のコードを書きました、そしてそれはルート値を正しく出力しますが、ret値は出力しません。ここでは、メモリアドレスが出力される可能性があります(1707388)。retを変更して、結果をメインに表示できるようになったと思います。どんな助けでも大歓迎です。

#include <stdlib.h>

struct node{
int value;
    int order;
    struct node *left;
    struct node *right;
};

typedef struct node node_t;

node_t array[10];

void createTree(node_t *p, int order){
    p->value = rand()%10;
    p->order = order;
    printf("%i", p->value);
    printf(" ");
    printf("%i\n", p->order);
    if (!order){
        p->left = NULL;
        p->right = NULL;
        return; 
    }
    order--;
    createTree(&p->left, order);
    createTree(&p->right, order);
}

void traverse(node_t *current, node_t *ret, int size){
    printf("%i\n", current->value); 
    if (current->value > size){
        ret = current;
        traverse(&current->left, &ret, size);
        traverse(&current->right, &ret, size); 
    } 
    return;
}

int main(void){
    node_t *root = &array[0];
    node_t *ret;
    srand(time(NULL));
    createTree(root, 4);
    int i = 3;
    printf("%s", "root-value: ");
    printf("%i\n", root->value);
    traverse(root, ret, i);
    printf("%s", "root-value: ");
    printf("%i\n", root->value);
    printf("%i\n", ret->value);
    return 1;
}
4

4 に答える 4

4

これ:

void createTree(node_t *p, int order)

する必要があります

void createTree(node_t **p, int order)

それ以外の場合は、関数外のポインターではなく、ローカル ポインターを変更します。node_tあなたのツリーも適切に構築されていません。

于 2013-03-24T15:38:02.210 に答える
3

retあなたは価値を渡しています

void traverse(node_t *current, node_t *ret, int size){

関数が変更retされても、変更は呼び出し元に伝播されません。

これは、retinが初期化されmain()ていないままであり、コードの動作が未定義であることを意味します。

これを修正するにはtraverse、returnを作成するかret、として取得しnode_t**ます。

于 2013-03-24T15:38:47.810 に答える
2

コードにはいくつかの問題があります。

まず、ノードにメモリを正しく割り当てていません。あなたのコードでは、間違ったポインタ型、さらには初期化されていない領域へのポインタを渡しています。

ここでは、それを別の方法で使用する方法を説明します。

 node_t *createTree(int order)
 {
     node_t *result = malloc(sizeof(*result));
     result->value = rand() % 10;
     result->order = order;
     if (order)
     {
         result->left = createTree(order - 1);
         result->right = createTree(order - 1);
     }
     else
     {
         result->left = result->right = 0;
     }
     return result;
 }

次に、トラバース関数には、失敗した検索を制限するためのブロックが必要です。

node_t *traverse(node_t *current, int size)
{
    node_t *ret = NULL;

    if (current->value > size)
    {
        // assuming current node fit - stops the search
        ret = current;
    } 

    if (!ret && current->left)
    {
        // try left node
        ret = traverse(current->left, size);
    }
    if (!ret && current->right)
    {
        // try right node
        ret = traverse(current->right, size); 
    }
    return ret;
}

あなたが必要とする場合(通常あなたはそうします)、ここにありますdestroyTree

void destroyTree(node_t *node)
{
    if (!node) return; // we treat NULL as a valid pointer for simplicity

    destroyTree(node->left);
    destroyTree(node->right);
    free(node);
}

そして、これが使用例です:

node_t *root, *found;

root = createTree(4);
found = traverse(root, 3);
if (found)
{
   printf("Found!");
}
destroyTree(root);
于 2013-03-24T15:51:23.253 に答える
1

traverse(node_t *current, node_t *ret, int size)retはスタック変数です。つまり、参照で渡すのではなく、でポインタを渡すことになります。

現時点で行ったことは、基本的に次のとおりです。

int f(int i) {
   ...
   i = <any value>;
   ...
}

この場合、値のコピーのみを変更します。

プログラムでは、ポインタのコピーも変更しています。関数の外では、ポインターは変更されません。

変更する場合は、ポインタを渡す必要があります。

void traverse(node_t *current, node_t **ret, int size){
    ...
    *ret = current;
    ...
    return;
}

についても同じですcreateTree()

于 2013-03-24T16:03:31.130 に答える