C - 二叉树:向树添加新的 child 时出错

C - Nary Tree: error while appending a new child to the tree

我正在使用如下结构在 C 中开发 Nary 树:

typedef struct sNaryNode { 
     int *data; // Point to the node ’s data
     int n; // The number of children 
     struct sNaryNode **child; // The child list
} NaryNode; 

typedef NaryNode NaryTree;

我不能使用列表(根据项目的要求)。 我能够创建树,但是当我尝试将新的 child 附加到树时,树的所有 "data" 值都被新值覆盖。例如:我用 data = 1 创建根,然后我想用 data = 2 附加一个新的 child,最后根和新的 child 具有相同的"data"值,即data = 2。我认为问题不是由于指针管理的错误,但由于我不知道我错在哪里,所以我决定征求您的意见。这是完整的代码:
lm_array2.h

#ifndef lm_array2_h
#define lm_array2_h

typedef struct sNaryNode { 
     int *data; // Point to the node ’s data
     int n; // The number of children 
     struct sNaryNode **child; // The child list
} NaryNode; 

typedef NaryNode NaryTree;
typedef void (*DataFreeFunc) (const void *);

void printArrayTree (NaryTree*);
NaryTree *createNode (int, int*);
void freeTree (NaryTree*, DataFreeFunc);
int appendChild(NaryNode*, int*);
void deleteChild (NaryTree*, int, DataFreeFunc);

#endif

lm_array2.c

#include <stdio.h>
#include <stdlib.h>
#include "lm_array2.h"

void printArrayTree (NaryTree *tree) {
    int d = *tree->data;
    printf("\n %d ", d);
    if (tree->n > 0) {
        int i;
        for (i = 0; i < tree->n; i++) {
            //printArrayTree (tree->child[i]);
            int dd = *tree->child[i]->data;
            printf("\n %d", dd);
        }

    }
    else {
        printf("\n-----\n");
        return;
    }
}

NaryTree *createNode ( int children , int *data) { 
    // Allocate space for a new NaryNode in memory
    NaryNode *node = (NaryNode*) calloc (1 , sizeof (NaryNode) );

    // Set the contents of the NaryNode appropriately
    node->data = data; 
    node->n = children ; 
    node->child = (NaryNode**) calloc ( children , sizeof (NaryNode*) );

    // Return the node we initialized
    return node;
}

void freeTree (NaryTree *tree , DataFreeFunc dFree) {
    unsigned i; 

    // Don’ t try this with a NULL pointer 
    if ( tree == NULL) return; 

    // Free the children recursively 
    for ( i = 0; i < tree->n; ++i ) 
        freeTree ( tree->child [ i ] , dFree); 

    // Free the child array 
    free ( tree->child ); 

    // Free the data if a function is provided 
    if (dFree) dFree( tree->data); 

    // And finally , free the structure 
    free ( tree ); 
}

 int appendChild(NaryNode *root , int *data) {
     // Increment the degree of the node 
     root->n++; 

     // Reallocate the child array (n children in the child array) 
     root->child = (NaryNode**) realloc ( root->child , ( root->n)*sizeof (NaryNode*) );

     // Add the newNode into the child array and increment degree 
     root->child [ root->n - 1] = createNode (0 , data); 

     // Return the index of the child we just inserted 
     return root->n - 1;  
 } 

 void deleteChild (NaryTree *root , int idx , DataFreeFunc dFree) {
     unsigned i; 

     // Delete the child 
     freeTree ( root->child [ idx ] , dFree); 

     // Remove the defunct child 
     for ( i = idx ; i < root->n - 1; ++i ) 
        root->child [ i ] = root->child [ i - 1]; 

     // And finally , reallocate 
     root->n--; 
     root->child = (NaryNode**) realloc ( root->child , ( root->n)*sizeof (NaryNode*) );
 }

main.c

#include <stdio.h>
#include <stdlib.h>
#include "lm_array2.h"
#include "lm_array2.c"

void menu(int*);

int main() {
    NaryTree *aTree = (NaryNode*)malloc(sizeof(NaryNode));
    int choice = 0, value;

    printf("\nEnter the root value: ");
    scanf("%d", &value);
    aTree = createNode (0, &value);

    do {
        menu(&choice);
        switch (choice) {

            case 1:
                printf("\nEnter the new child value: ");
                scanf("%d", &value);
                //NaryTree *aNode = createNode (0, value);
                appendChild(aTree, &value);
                break;

            case 2:
                //printf("%d", *aTree->data);
                printArrayTree(aTree);
                break;

            case 3:
                printf("\n\n***THE END***\n\n");
                break;
        }
    } while (choice > 0 && choice <= 2);

    system("PAUSE");

    return 0;
}

void menu(int *choice){
    printf("\n");
    printf("1. Insert new child\n");
    printf("2. Print NaryTree\n");
    printf("3. Exit");
    printf("\nEnter your choice: ");
    scanf("%d", &*choice);
}

所有代码(除了主要代码)都取自这里 --> CLICK HERE

我们将不胜感激任何帮助或建议。提前致谢:)

您的错误出在节点的初始化中:您没有为数据分配内存缓冲区。你让它指向你的参数,即在堆栈上而不是在堆上。一旦您的 createNode 函数结束,堆栈就会清空并且您的参数(因此您的数据值)将丢失。

NaryTree *createNode ( int children , int *data) { 
    // Allocate space for a new NaryNode in memory
    NaryNode *node = (NaryNode*) calloc (1 , sizeof (NaryNode) );

    // Set the contents of the NaryNode appropriately
    // node->data = data; 
    node->data = malloc(sizeof(node->data));
    *node->data = *data;
    node->n = children ; 
    node->child = (NaryNode**) calloc ( children , sizeof (NaryNode*) );

    // Return the node we initialized
    return node;
}

或者,更简单:

typedef struct sNaryNode { 
     // int *data; // Point to the node ’s data
     int data; // contains the node ’s data
     int n; // The number of children 
     struct sNaryNode **child; // The child list
} NaryNode;

并直接传递给 createNode int 数据而不是指针:

NaryTree *createNode ( int children , int data) { 
    // Allocate space for a new NaryNode in memory
    NaryNode *node = (NaryNode*) calloc (1 , sizeof (NaryNode) );

    // Set the contents of the NaryNode appropriately
    // node->data = data; 
    node->n = children ; 
    node->child = (NaryNode**) calloc ( children , sizeof (NaryNode*) );

    // Return the node we initialized
    return node;
}