I'm trying to count total of leaves that have even numbers in a BST.
Example: root--> 2 4 6 8 9
Output: 4 leaf that have even numbers.
Here is what I have done:
struct BSTNode
{
BSTNode* left;
BSTNode* right;
int data;
};
int CountingTotalEven(BST* root)
{
int count = 0;
count++;
CountingTotalEven(BST* root);
return count;
}
My program output wrong number, I don't know what I'm doing wrong.
int count = 0;
count++;
CountingTotalEven(BST* root);
return count;
There are three main issues in this code currently. Firstly, you're initializing count in your recursive function as a non-static variable. So what happens is count gets initialized as 0 every time this recursive function is called.
Secondly, you've called the recursive function on the root again. What you want to do is call the function recursively for its right and left subtrees(read: Tree Traversals).
Thirdly, you're not checking if the value is actually even.Change your function to
static int count = 0;
if(count%2 == 0)
count++;
CountingTotalEven(root->left);
CountingTotalEven(root->right);
return count;
Related
Trying to write a program which will sum all odd elements of binary tree. But my code (function odd_sum) returns only first odd element. Where is my mistake?
/*Creating abd printing tree*/
int odd_sum(node *root)
{ if (root == NULL) return 0;
return root->info % 2 != 0 ? root->info:0 + odd_sum(root->left) +
odd_sum(root->right);
}
int main()
{
int k,sum,h=0;
node *der=tree();
if (!der) printf ("No tree");
else
{
node *root=der,*qwe=der;
sum=odd_sum(root);
print_tree(der,h);
printf ("\nOdd sum :%d\n\n\n",sum);}
return 0;
}
If you meet an odd value in the tree you are just returning its value without branching down the tree, that's why you get only the first odd number.
The corrected version of your code is on the line of:
int odd_sum(node *root){
if (root == NULL) {
return 0;
}
else {
int add = 0;
if(root->info % 2 != 0) add = root->info;
return add + odd_sum(root->left) + odd_sum(root->right);
}
}
You need to traverse down the tree and whenever you find the node with odd value you can update your Sum variable.
void oddSum(node *root, int &Sum){
if(!root)
return;
if((root->val) & 1)
Sum += root->val;
oddSum(root->left, Sum);
oddSum(root->right, Sum);
}
Pass the root and Sum variable with reference, at the end of the recursion, you will find the sum of the odd values of tree stored in Sum.
int list::Sum_Even_Values(node *head)
{
static int sum=0;
if(!isempty())
{
if(head->info %2==0)
return head->info +Sum_Even_Values(head->next);
}
}
When you are writing a function that returns a value, recursive or not, you need to explore all paths through the code, not only your main "path of interest."
In your specific case you need to decide what to return
When the current node represents an even number - your code already covers this case,
When the current node represents an odd number - you need to return the same value as if the node is not there, and
When there is no current node - that's the value you'd return when the list is null or empty (i.e. zero).
You need to add return statements for the remaining two cases. Once you do that, your function would be complete.
Here is another way to achieve the same thing by passing the sum variable by reference at every call to the function.
void sumEvenValues(Node * head, int& sum){
if (head != NULL){
if (head->info % 2 == 0){
sum += head->info;
}
sumEvenValues(head->next, sum);
}
}
Don't use a static variable, as you won't be able to reset it back to 0 if you need to sum the list multiple times. Try this instead:
int list::Sum_Even_Values(node *head)
{
int sum = 0;
if (head) {
if ((head->info % 2) == 0)
sum = head->info;
sum += Sum_Even_Values(head->next);
}
return sum;
}
Live Demo
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 andmakes 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.
I am trying to build a huge binary search tree:
class Node
{
public:
int value;
shared_ptr<Node> left;
Node* right;
Node(int v):value(v){}
void addLeft(){
static int i;
shared_ptr<Node> node=make_shared<Node>(i);
left=node;
cout<<i++<<endl;
if(i<60000)
node->addLeft();
}
};
int main(){
shared_ptr<Node>root=make_shared<Node>(9);
root->addLeft();
return 0;
}
I get a seg fault over running this code, in valgrind I have this report:
==17373== Stack overflow in thread #1: can't grow stack to 0xffe801000
Any clue on how to build the BST without overflowing the RAM space?
Any help is much appreciated
Exceeding the stack is not the same as exceeding your RAM. Function calls accumulate on the stack, the problem is you are trying to place 60000 function calls and variables on the stack. Convert your function to a loop and you will be fine. It will even get rid of that terrible static int i.
Here is a version of your function using a for loop with no recursion.
void addLeft()
{
left = std::make_shared<Node>(0);
// tail is the last element to have been added to the tree
std::shared_ptr<Node> tail = left;
std::cout << 0 << std::endl;
// Add nodes from 1 to 60000 inclusively
for (int i = 1; i <= 60000; ++i)
{
std::cout << i << std::endl;
tail->left = std::make_shared<Node>(i);
tail = tail->left;
}
}
Is there a way to find the number of elements in the binary search tree?
struct node
{
node *p, *left, *right;
int key;
};
This is my node's structure, p pointer is pointing to the parent element.
I need to find that number to allocate memory for searching the tree and returning an array with all elements.
I've came up with something like this:
int numberOfElements(node *root, int count = 0)
{
if(root)
{
numberOfElements(root->left, ++count);
numberOfElements(root->right, ++count);
}
return count + 1;
}
But well, it shows some random results :P For "1, 2" is displays 2, for "1, 2, 3, 4, 5, 6, 7" it displays 3 etc...
I want to do this inside one function, that's why count is an argument here.
How can I do this?
You don't need the second argument:
int numberOfElements(node *root) {
if (root) {
return 1 + numberOfElements(root->left) + numberOfElements(root->right);
} else {
return 0;
}
}
You don't seem to use the return value of numberOfElements at all.
This version might work:
int numberOfElements(node *root)
{
if(root)
{
return numberOfElements(root->left) +
numberOfElements(root->right) + 1;
}
return 0;
}
Generally, the size of such a tree should be recorded in a field, and gets updated every time you modify the tree. No one expects O(N) running time just to find the size of a tree.