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;
}
我正在使用如下结构在 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;
}