释放为树分配的内存 - C.

时间:2010-08-14 14:14:00

标签: c algorithm memory-management tree

我有一个定义的树,

struct tree {
    char label[MAX_LENGTH];
    char value[MAX_LENGTH];
    struct tree *child;
    struct tree *next;
};

现在我需要释放这棵树分配的内存。我写了下面的代码。

unsigned int tree_free(struct tree *root)
{
    struct tree *current = NULL, *next = NULL, *child = NULL;
    unsigned int freecnt = 0;

    current = root;
    while(current != NULL)
    {
        next = current->next;
        child = current->child;      
        xfree(current);
        freecnt += tree_free(child) + 1;
        current = next;
    }
    return freecnt;
}

此方法返回已释放的项目数,以便我可以根据分配的数量对其进行验证。这段代码有效。但我不确定这是正确的做事方式。

这是后缀树实现。对于项目s,堆栈,覆盖,溢出,堆栈溢出,树将看起来像

root
-s
--stack
---stackoverflow
-over
--overflow

欢迎任何改进代码的建议。

2 个答案:

答案 0 :(得分:2)

如果你需要释放一棵树,你需要走它,所以我认为代码是正确的。我会以同样的方式完成它(递归地走树,沿途释放物体)。我唯一要做的就是在递归后运行xfree(即交换xfree(current);freecnt += tree_free(child) + 1;)。因为现在您在删除子节点之前删除了节点,但我觉得在删除父节点之前删除子节点会更好。

此外,您可以删除child变量,因为您只需要使用一次,但确实需要。每次递归会为你保存sizeof(pointer)堆栈空间; - )

答案 1 :(得分:1)

这是一个相当不错的解决方案。你正在为孩子们使用递归(这不会太深)但是为兄弟姐妹进行迭代(如果使用递归,深入)。作为一个仅递归的解决方案(对tree_freechild都调用next),你的代码肯定会更优雅,但是堆栈溢出的风险会大大增加,所以我认为你做了正确的选择。

话虽如此,如果您重新安排运营顺序,则根本不需要child

unsigned int tree_free (struct tree *root) {
    struct tree *current = NULL, *next = NULL;
    unsigned int freecnt = 0;

    current = root;
    while(current != NULL)
    {
        freecnt += tree_free (current->child) + 1;
        next = current->next;
        xfree (current);
        current = next;
    }
    return freecnt;
}

如果您认为兄弟列表的长度不会那么大,您可以尝试优雅的解决方案:

unsigned int tree_free (struct tree *root) {
    unsigned int freecnt;

    if (root == NULL) return 0;
    freecnt = tree_free (root->child) + tree_free (root->next);
    xfree (root);
    return freecnt + 1;
}

这是未经测试的,因此我没有声明保修或适用性,特别是因为它可能对您的大量兄弟链接的特定情况有危险。我更多地将其包含在内,表明递归的可能性。我的建议是使用第一个。