我正在使用C这样的结构开发Nary Tree:

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;


我不能使用列表(按项目要求)。
我可以创建树,但是当我尝试将新的子项添加到树时,树的所有“数据”值都将被新值覆盖。例如:我用data = 1创建根,然后我想用data = 2附加一个新子级,最后,根和新子级都具有相同的“数据”值,即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;
}

关于c - C-Nary树:将新子项附加到树时出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30257256/

10-09 21:20