如何释放一棵树?

时间:2015-01-19 20:06:03

标签: c tree

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

我有什么:

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 ****

2 个答案:

答案 0 :(得分: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));
}

答案 1 :(得分:0)

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

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