【问题标题】:How to free a tree?如何释放一棵树?
【发布时间】:2015-01-19 20:06:02
【问题描述】:

释放一棵树的递归函数。一个可以从树中获取任何节点的参数。每个节点都包含一个指向父节点和子节点的指针。没有辅助函数,也没有其他参数。

我有什么:

void freeTree(Node *node)
{
  int i, j;
  Node *parent = node->parent;
  for (i = j = 0; i < node->nChild; i++) {
    if (node->child[i]) {
      j++;
      freeTree(node->child[i]);
    }
  }
  if (j != 0 && parent != NULL) {
    freeTree(parent);
  } else {
    free(node);
  }
}

*** 错误:双重释放或损坏(fasttop):0x000000000XXXXXXX ****

【问题讨论】:

    标签: c tree


    【解决方案1】:

    将代码拆分成几个函数会更容易阅读和理解。

    Node* findRoot(Node* node) {
        if (node->parent) {
            return findRoot(node->parent);
        }
        return node;
    }
    
    void freeNode(Node* node) {
        int i;
        for (i = 0; i < node->nChild; i++) {
            if (node->child[i]) {
                freeTree(node->child[i]);
            }
        }
        free(node);
    }
    
    void freeTree(Node* node) {
        freeNode(findRoot(node));
    }
    

    【讨论】:

    • 进入无限循环:freeTree(child), freeTree(parent), freeTree(child), freeTree(parent)...
    • 哦,是的,我看到了 pb 是什么,让我更新代码。
    • 以更有效的方式进行编辑。
    • 我没有写结构体,也不允许我编辑结构体。
    • 新的编辑可能更清楚会发生什么,而且您还可以以一个价格获得 3 个功能。
    【解决方案2】:

    如果您使用的是根节点,这很容易,只需为所有子节点递归调用该函数,然后释放您所在的节点。找到根很容易,只需递归调用父函数,如果有一个然后返回。到达没有父节点的节点后,从所有子节点中删除父链接,使它们成为自己树的根,为它们递归调用函数,然后释放您所在的节点。

        A
       / \
      B   C
         / \
        D   E
    

    如果您使用DE 调用该函数,它将为C 调用自身并返回。如果使用BC 调用,它将使用A 调用自身并返回。当调用A 时,由于没有父节点,它将从BC 中删除父链接,为BC 调用自身,释放节点A 并返回。现在B 没有父级,它将释放自己。由于C 不再有父级,它将从DE 中删除父级链接,然后为它们调用自身,释放节点C 并返回。

    void freeTree(Node *node)
    {
        int i;
    
        /* find root node */
        if (node->parent) {
            freeTree(node->parent);
            return;
        }
    
        for (i = 0; i < node->nChild; i++) {
            node->child[i]->parent = NULL; /* no parent so will free it and children */
            freeTree(node->child[i]);
        }
        free(node);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-21
      • 1970-01-01
      • 2016-05-19
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多