2011-03-21 159 views
0

我做了一个只有根的树结构。然后,由用户决定是否创建节点,并将它们作为子节点添加到根节点或其他现有节点。下面是结构的外观:C:如何将节点添加到循环中的树中?

#define MAXCHILDREN 5  //max children a node can have 

typedef struct node{ 
    unsigned int id; 
    struct node* parent; 
    struct node* children[MAXCHILDREN]; 
}node; 

typedef struct spantree{ 
    node root; 
}spantree; 

现在我想实现的目标就是说4个节点并将它们作为子节点添加到根节点。下面是我做了什么不正常工作:

for (i=0; i<4; i++){ 
     node newNode; 
     newNode.id=i; 
     addChild(&newNode, &Root); 
    } 

这不,当我运行

showChildId(0,&根)的工作; //其中第一个数字表示的第一个孩子,第二个孩子等

showChildId(1,&根);

我得到这意味着只有一个孩子添加相同的ID。所以,我怎么去在一个循环做4个不同节点并将其添加到父(在这种情况下根)?

+0

我在该级别的算法中看不到任何错误,您是否可以提供其他函数的实现? – Alexis 2011-03-21 10:37:44

+0

@Alexis:不需要。该错误包含在该代码中。 – GrahamS 2011-03-21 10:45:30

+0

@Alexis我尝试尽可能地简化它。这里是一个示例准备运行http://pastebin.com/290ABdmt – Pithikos 2011-03-21 10:57:24

回答

1

这看起来像功课给我,让我会尽力提供指导,而不是一个明确的答案。

在这个循环中:

for (i=0; i<4; i++){ 
    node newNode; // <-- newNode is created on the stack here . 
    newNode.id=i; 
    addChild(&newNode, &Root); 
        // <-- and is removed from the stack here. 
} 

newNode是在栈上创建的循环的每次迭代,这是唯一有效的,直到迭代结束。

为了使它的寿命更长,你需要分配一些内存为它在堆上。看看malloc()free()

+0

谢谢加载!事实上,这远远超出了家庭作业的限制,但它让我感到困惑。我希望在不使用malloc()的情况下实现这一点,因为当我需要释放时,它会变得更加复杂,但是要感谢指导! – Pithikos 2011-03-21 11:07:09

+0

如果你真的**想避免malloc,那么它是*可能*,但很难。例如,你可以创建一个大型的'node'静态数组(即''static node allmynodes [500];')。然后当你需要一个新的节点时,你可以在该阵列中使用一个节点但是您还需要跟踪阵列中哪些节点正在使用,并处理使用阵列中所有节点的可能性。 – GrahamS 2011-03-21 11:17:34

3

你加入临时值到子列表:

node newNode; 

这将创建一个只存在,直到下面的“}”在堆栈上的衣被合计。下一次迭代很可能会为新对象重新使用同一块内存。你需要动态创建的对象,而不是堆栈中分配的:

node *newNode = malloc sizeof (node); 
newNode->id = i; 
addChild (newNode, &Root); 

你需要确保节点被正确释放,否则你会泄漏内存。释放节点内存的函数应该为每个子节点递归调用它自己。

+0

我希望避免malloc,但它似乎是不可能的:/ – Pithikos 2011-03-21 11:10:39

1

与亚历克西斯,我什么也看不见就在这里,在这个级别的算法,但我不知道,如果你跳过细节或混乱。

for (i=0; i<4; i++){ // I think you mean 5 here -- or rather MAXCHILDREN. 
     node newNode; // This is a temporary on the stack. 
     newNode.id=i; 
     addChild(&newNode, &Root); // &newNode is a pointer to that temporary. 
    } 

所以addChild每次都得到一个指向临时newNode的指针。它恰好位于堆栈中的相同地址,所以它们都指向相同的地方。所以他们都有相同的ID。那个栈位置可能已经被覆盖了,所以它可能是一些完全随机的值。

for (i=0; i<MAXCHILDREN; i++){ 
     node *newNode = new node(); // C++, or use malloc if you're stuck in C 
     newNode->id=i; 
     addChild(newNode, &Root); 
    } 

应该让你更接近你想要做的事。

+0

标签和问题标题都说OP使用C,所以它必须是'malloc'''' free'''''''''''''' – GrahamS 2011-03-21 11:06:43