【问题标题】:How to prune tree data structure at given depth in C如何在C中给定深度修剪树数据结构
【发布时间】:2017-01-05 20:34:58
【问题描述】:

我正在尝试编写这个函数:

struct treeNode *pruneTree(struct treeNode *root, int depth);

给定一棵像这样的树:

          1           level 0
         / \
        2   3         level 1
       / \    \
      4  5     6      level 2
     / \
    7   8             level 3

如果 depth = 1 则创建一个 depth = 1 的树并切割之后的所有内容,因此结果应该是:

          1
         / \
        2   3  // tree with depth = 1

我知道如何编写一个修剪叶子的函数,我正在尝试使其适应任何级别的修剪:

int isLeaf (struct treeNode * treeNode) {
    return (treeNode->left == NULL) && (treeNode->right == NULL);
}

void removeLeaves(struct treeNode * root) {
    if (root->left != NULL) {
        if (isLeaf (root->left)) {
            free(root->left);
        }
        else {
            removeLeaves(root->left);
        }
    }

    if (root->right != NULL) {
        if (isLeaf (root->right)) {
            free(root->right);
        }

        else {
            removeLeaves(root->right);
        }
    }
}

有什么好的策略来做到这一点?我的方法是用isAfterDepth 函数替换isLeaf 函数并使用计算深度的辅助函数,但这似乎效率不高。有什么更优雅的方式来做到这一点?

【问题讨论】:

  • 不应该先free/delete 节点吗?这看起来像是一个会产生内存泄漏的程序。
  • 我修改了程序以反映这一点。
  • 另一个问题:你只做一个副本?你不改变给定的树?
  • 现在我可以修改原始树了。我有一个函数 cloneTree 可以用来不改变原始文件。

标签: c data-structures tree


【解决方案1】:

复制树

如果您打算复制在某个级别被修剪的树,您可以简单地使用递归,并且在每次递归调用时将深度参数减一,如果深度导致0,您不再递归地复制孩子。

struct treeNode *pruneTree(struct treeNode *root, int depth) { //version where the tree is copied
    if(root == NULL || depth < 0) {
        return NULL;
    } else {
        treeNode *copyRoot = (treeNode*) malloc(sizeof(treeNode));
        copyRoot->value = root->value;
        copyRoot->left = pruneTree(root->left,depth-1);
        copyRoot->right = pruneTree(root->right,depth-1);
        return copyRoot;
    }
}

代码的工作方式如下:如果给定的root指针是NULL或thdepth小于零,则返回NULL,因为我们要么用叶子的孩子调用它,要么用深度调用它已达到约束。

如果不是这样,我们复制当前节点:我们分配一个新的treeNode对象,复制原始节点的value(假设这称为value),然后执行一个递归调用以复制 leftright 子代。

改变树

您还可以更改当前树。在这种情况下,您最好先定义一个函数来删除子树及其所有后代:

void prune(struct treeNode * root) {
    if(root != NULL) {
        if (root->left != NULL) {
            prune(root->left);
        }
        if (root->right != NULL) {
            prune(root->right);
        }
        free(root);
    }
}

现在我们只需要定义一个只在特定级别进行修剪的方法:

struct treeNode *pruneTree(struct treeNode *root, int depth) { //version where the tree is altered
    if(root != NULL) {
        if(depth <= 0) {
            prune(root->left);
            root->left = NULL;
            prune(root->right);
            root->right = NULL;
        } else {
            pruneTree(root->left,depth-1);
            pruneTree(root->right,depth-1);
        }
    }
    return root;
}

【讨论】:

  • 很好,你添加了......我现在没有足够的时间来写重要的答案......谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多