我正在尝试编写此函数:
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,则创建一个深度为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);
}
}
}
这样做的好策略是什么?我的方法是用isLeaf
函数替换isAfterDepth
函数并使用计算深度的辅助函数,但这看起来效率不高。什么是更优雅的方式呢?
答案 0 :(得分:1)
如果您想要复制在某个级别修剪的树,您可以简单地使用递归,并且在每次递归调用时将深度参数减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
或者depth
小于零,则会返回NULL
,因为我们将其称为叶子的孩子或深度约束已经到达。
如果不是这样,我们制作当前节点的副本:我们分配一个新的treeNode
对象,复制原始节点的value
(假设这被称为value
}),并执行递归调用以复制left
和right
个孩子。
您还可以更改当前树。在这种情况下,您最好先定义一个函数来删除子树及其所有后代:
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;
}