C++: Odd sum of values of the binary tree - c++

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.

Related

How to find sum of even numbers in a list using recursion in c++?

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

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 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.

Recursive tree, printing ancestor nodes

this is study material, not homework:
I have the following tree, I need to write an algorithm that finds a given number and returns an integer indicating how many nodes it visited before finding it. It should also print the values of all "ancestor" nodes relative to the node in which the value was found (in no particular order, and it is assumed that the given value is always present)
10
/ \
20 60
/ \
50 30
\
40
If the given value is 40 it should return 4 and print 30, 20, 10 (in any order)
I've written the following solution, and I think it works, but I'm concerned about the print.
void foobar (ty_tree *tree, int value, int & count){
if (tree !=null) {
if (tree->value != value) {
count++;
foobar (tree->left, value, count);
foobar (tree->right, value, count);
cout << tree->value;
}
}
}
Good approach ! But to print the ancestors (i.e.parent nodes) you need to know in your recursive function if the value was found in one of the child:
bool foobar (ty_tree *tree, int value, int & count) {
if (tree !=nullptr) { // oops: NULL or nullptr, the latter is better
if (tree->value != value) {
count++;
if (foobar (tree->left, value, count) ||
foobar (tree->right, value, count) ) // if found below
cout << tree->value<<endl; // print the node, because it's on the path
}
else {
cout << "Found: "<<tree->value<<endl; // print the value found
return true; // and inform caller that he can print as well.
}
}
else return false; // reached a leaf without finding
}
As some doubts were expressed in the comments, here an online demo

To find height of a binary search tree

/*
* To find the Height of a BST tree
*/
public void findHeight(){
if(this.root == null){
System.out.println("BST Tree is Empty ");
}
else
findHeight(this.root);
}
public int findHeight(Tnode temp){
if(temp == null){
System.out.println("BST Tree is Empty ");
return -1;
}
else{
return 1 + Math.max(findHeight(temp.getLeft()) ,findHeight(temp.getRight()) ) ;
}
}
Program is running infinitely.Not able to find the reason , It would be helpfull ,if some one guides me
Thanks in advance
Are you sure the findHeight() function doesn't return anything? Are you expecting anything from that function? Posting more code would help.
"BST Tree is Empty" will also be printed at every terminal leaf of the tree.
To find out what's going on, you could add some debugging output:
private spaces(int len){
String s = " ";
while (s.Length < len) {
s += " ";
}
return s.substring(0, len);
}
public int findHeight(Tnode temp, int nesting, String msg){
String margin = spaces(2*nesting);
if(temp == null){
System.out.println(margin + msg + ": no sub-tree to explore");
return -1;
}
else{
System.out.println(margin + msg);
int hl = findHeight(temp.getLeft(), nesting + 1, "left");
int hr = findHeight(temp.getRight(), nesting + 1, "right");
return 1 + (hl >= hr ? hl : hr) ;
}
}
Your endless recursion might be due to some error in your tree structure. If your left/right child references are never null, the recursion won't terminate.

Trouble printing Map/Filter/Reduce functions in C

I'm having a really hard time understanding why I keep getting an exception, when my function returns the value with ease, but once i try to printf the result it gives me an unhandled exception error(see below) I'm new to C so I've been looking at everything from a java perspective and I cant figure it out.
Heres my relative code (reduce takes a linkedlist, which is an array of nodes containing an int value, and a pointer to the next node in the list, the last node points to null)
int reduce(int (*func)(int v1, int v2), LinkedListP list, int init){
int i, sum;
struct node *first, *second;
sum = 0;
first = list->head;
second = list->head->next;
for(i = 0;i < list->count; i+=2)
{
//checks to see if there are values in the list at all
if(first == NULL)
{
return sum;
}
//if first value is good, and the second value is null, then sum the final one and return the result
else if(second == NULL)
{
sum += func(first->value, init);
return sum;
}
//otherwise there is more to compute
else
{
sum += func(first->value, second->value);
}
//first now points to the next node that seconds node was pointing to
first = second->next;
//if the first link is null, then there is no need to assign something to the second one
if(first == NULL){
return sum;
}
else{
second = first->next;
}
}
}
and in main I pass a pointer to a function called sum which just adds two values together
simple code
newLink = new_LinkedList();
int(*reduceFunc)(int, int);
reduceFunc = sum;
result = reduce(sum, newLink, 0);
printf("Total is : %s", result );
now that all throws this VVVVVVVV
Unhandled exception at 0x1029984f in ExamTwo.exe: 0xC0000005: Access violation reading location 0x00000015.
Your reduce() function is returning an int, but you're giving printf() the format code for a string. Try
printf("Total is : %d", result );
You need to replace %s with %d in the printf.