简体   繁体   中英

storing the number of certain leaves in the nodes of the binary search tree(optimization)

I have to count for each subtree the number of leaves with even label whose father has odd label and the number of leaves with odd label whose father has even label and store that number in the subtree's node.

For example : this tree (the output is on the left).

This is my code

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

It works, what is not fine are the functions "counter" and "updateNode" together.

"Counter" counts the number of leaves that are to be counted.

"UpdateNode" utilizes "counter" to count and then store the number of leaves in each subtree into L (which i defined in the struct).

This way i have a recursive function into another recursive function and i visit each node multiple times.

How can i optimize my code?

This way i have a recursive function into another recursive function and i visit each node multiple times.

The part before and makes your code ugly, but the real devil lies in how you chose to traverse the tree.

In your updateNode function, the value of L for a node is simply sum of it's left and right subtree. So instead of calling them at the end of your function (preorder) like you do now, if you call them earlier (postorder); now you know their L and instead of calling counter , you simply add them up. You visit every node exactly once.

You can completely delete your counter function.

Here is modified code (comments explain the code) :

//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
}

And driver to run it:

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

And..your addnodeBST will fail for equal values. Change the second if to else .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM