C - Nary Tree:将新子项附加到树时出错

时间:2015-05-15 10:30:45

标签: c tree children appendchild

我正在使用这样的结构在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;

我无法使用List(根据项目需要)。 我能够创建树,但是当我尝试将新的子项附加到树上时,所有的数据都是#34;树的值被新值覆盖。例如:我使用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);
}

所有代码(主要除外)都取自此处 - &gt; CLICK HERE

我们将非常感谢您的每一个帮助或建议。在此先感谢:)

1 个答案:

答案 0 :(得分:1)

您的错误在于节点的初始化:您没有为数据分配内存缓冲区。你使它指向你的参数,即在堆栈上而不在堆上。一旦您的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;
}