【发布时间】:2017-09-13 15:46:46
【问题描述】:
我有一个 n 叉树结构,就像答案 here 中解释的那样:
typedef struct node {
int ID;
struct node *child; // points to (first) child
struct node *next; // points to next node at same level (sibling)
struct node *parent; // points to parent
} node;
节点是使用malloc 创建的。
我想编写一个函数,将树的根更改为另一个(指定)节点,并释放所有节点的内存 - 由于根的更改 - 不再是树的一部分(即如果一个节点不能通过父节点追踪到新的根节点,它应该设置为NULL,并且它的内存应该被释放)。
例如,如果这是我的树:
1
/ \
2 3
/ \ \
4 5 6
/ \
7 8
我想把root从1改成3,然后调用prune_tree函数后,root就是3,除3和6之外的所有节点的内存都被释放了。
我最接近解决我的问题涉及到这个功能:
void prune_tree(node **root, node *new_root) {
if (*root == NULL || (*root)->parent == new_root)
return;
prune_tree(&((*root)->child), new_root);
prune_tree(&((*root)->next), new_root);
free(*root);
*root = NULL;
}
调用这个函数后我设置了
root = new_root;
我来到这里主要是通过反复试验;事实上,我什至不确定为什么在我测试它的大部分时间它都有效。它还添加了可能不必要的步骤,即在调用函数后必须将根设置为新的根地址。我假设有一种方法可以修改函数中的根地址,或者返回新的根地址。
我认为我不需要担心内存使用,因为该函数正在释放内存,但更可取的是省时的函数。我不确定这是否意味着我应该避免递归......
【问题讨论】:
-
对于返回新地址的方法,您可以使用调用递归
prune_tree& 返回新根的包装函数。然后将调用包装函数而不是原来的prune_tree。