我必须为每个子树计算带有偶数标签的叶子的数量,其父亲具有奇数标签,带有奇数标签的叶子的数量,其父亲甚至具有标签并将该数字存储在子树的节点中。
例如:this tree(输出在左侧)。
这是我的代码
struct node {
int label;
node*right;
node*left;
int L; //i use this to store the number of leaves
};
void addnodeBST(node*&tree, int l) { //adds a node
if (!tree) {
tree = new node;
tree->label = l;
tree->right = tree->left = 0;
tree->L = 0;
return;
}
if (l < tree->label)
addnodeBST(tree->left, l);
if (l > tree->label)
addnodeBST(tree->right, l);
}
int counter(node*tree, int x) {
if (!tree)
return 0;
if ((!tree->left && !tree->right) && ((x % 2 == 0 && tree->label % 2 ==
1) || (x % 2 == 1 && tree->label % 2 == 0)))
return 1;
return counter(tree->left, tree->label) + counter(tree->right, tree-
>label);
}
void updateNode(node*tree) {
if (!tree)
return;
tree->L = counter(tree, 0);
if (!tree->right && !tree->left)
tree->L = 0;
updateNode(tree->left);
updateNode(tree->right);
}
它有效,不一样的是“counter”和“updateNode”功能。
“计数器”计算要计算的叶数。
“UpdateNode”使用“counter”来计算,然后将每个子树中的叶子数存储到L中(我在结构中定义)。
这样我有一个递归函数到另一个递归函数,我多次访问每个节点。
如何优化代码?
答案 0 :(得分:0)
这样我有一个递归函数到另一个递归函数,我多次访问每个节点。
and
之前的部分使你的代码变得丑陋,但真正的魔鬼在于你如何选择遍历树。
在updateNode
函数中,节点的L
值只是它左右子树的总和。因此,如果您之前调用它们(后序),而不是像现在这样在函数结束时调用它们(预订);现在你知道了他们的L
,而不是打电话给counter
,你只需将它们添加起来即可。您只需访问每个节点一次。
您可以完全删除counter
功能。
这是修改后的代码(注释解释代码):
//helper to check leaves, null nodes are not leaf
bool isLeaf(node* tree){
return (tree && (!tree->right) && (!tree->left));
}
//change return type to catch child node's 'L' value through recursive calls
int updateNode(node*tree) {
if (!tree) return 0; //0 for null, for example tree->right for '24'
if (isLeaf(tree)) tree->L = 0; //All the leaves
int a,b;
//find 'L' for left child into a
if(isLeaf(tree->left)){
if(tree->left->label%2!=tree->label%2) a=1; //this will be true for '24' and '10'
else a=0;
}
else a = updateNode(tree->left);
//Now find 'L' for right child into b
if(isLeaf(tree->right)){ //this will be true for '10'
if(tree->right->label%2!=tree->label%2) b=1;
else b=0;
}
else b = updateNode(tree->right);
//combine them
tree->L = a+b; //this will be true for '20'
return tree->L; //return for parent's sake
}
驱动程序运行它:
void inorder(node* tree){
if(!tree) return ;
inorder(tree->left);
printf("%d : %d %d\n",tree->label,tree->L,isLeaf(tree) );
inorder(tree->right);
}
int main(int argc, char const *argv[])
{
node* tree = 0;
addnodeBST(tree,20);
addnodeBST(tree,10);
addnodeBST(tree,24);
addnodeBST(tree,17);
addnodeBST(tree,23);
addnodeBST(tree,5);
updateNode(tree);
inorder(tree);
return 0;
}
并且......你的addnodeBST
将因同等价值而失败。将第二个if
更改为else
。