代码之家  ›  专栏  ›  技术社区  ›  Navaneeth K N

释放分配给树的内存-C

  •  2
  • Navaneeth K N  · 技术社区  · 14 年前

    我有一棵树的定义是,

    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,stack,over,overflow,stackoverflow,树将如下所示

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

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

    2 回复  |  直到 14 年前
        1
  •  2
  •   DarkDust    14 年前

    如果你需要释放一棵树,你需要走它,所以我认为代码是正确的。我也会这样做(递归地遍历树,沿途释放对象)。唯一不同的做法是在递归(即交换)之后运行xfree xfree(current); freecnt += tree_free(child) + 1; ). 因为现在你先删除一个节点,然后再删除它的子节点,但是我觉得最好先删除子节点,然后再删除父节点。

    child 变量,因为你只使用它一次,与一个真正的需要。会救你的 sizeof(pointer) 每个递归的堆栈空间;-)

        2
  •  1
  •   paxdiablo    14 年前

    这是一个相当好的解决办法。您对子级使用递归(这不会太深入),但对兄弟级使用迭代(这 如果使用递归,请深入研究)。作为仅递归的解决方案(调用 tree_free 两者皆适用 child next

    话虽如此,也没有必要 小孩 如果你重新安排你的行动顺序:

    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;
    }
    

    它是未经测试,所以我不保证或适用于目的声明,特别是因为它可能是危险的,为您的大量兄弟链接的具体情况。我把它更多地作为递归的一个可能的指示。我的建议是用第一个。