Why does my function(on binary tree) print an unexpected result? - c++

I wanna a make function , which takes as parametrs a binary tree ,t, and two integers a,b and prints how many integers are between a and b...
As example here is a binary tree ,with three nodes and data :
10,15,20.
I call this function for example : between(t ,10 ,20) and as result i expect the number 1 , but this does not happen..
My function is :
`
int between (tree t, int a, int b) {
if (t== NULL)
return 0;
if ((t->data >a ) && ( t->data <b))
return 1 + between(t->left,a,b) + between(t->right,a,b);
}
Can anyone explain me ?

First of all, if the number is not between a and b, you have not defined a return value, which is an error other than your program doesnt do what it is required, but the function doesnt return an int value.
Secondly, you should go on, when the value is not on your range.
Your function should look like this:
int between (tree t, int a, int b) {
if (t== NULL)
return 0;
if ((t->data >a ) && ( t->data <b))
return 1 + between(t->left,a,b) + between(t->right,a,b);
else return between(t->left,a,b) + between(t->right,a,b);
}
Better yet, IF the values on the left are lower than values on the right (search tree) you can make an improvement.
int between (tree t, int a, int b) {
if (t== NULL)
return 0;
if ((t->data >a ) && ( t->data <b))
return 1 + between(t->left,a,b) + between(t->right,a,b);
else if(t->data<a)
return between(t->right,a,b);
else if(t->data>b)
return between(t->left,a,b);
}

Related

Function to find number of nodes below a certain depth of a BST

I'm trying to make a function that will count the number of nodes greater than a certain depth "k".
Here is my code of the function for traversing the tree and a helper function for finding the depth of each node:
int findDepth(BinaryNode * t, int value, int depth){
if( t == nullptr ){
return 0;
}
if( t->element == value){
return depth;
}
int lowerDepth = findDepth(t->left, value, depth+1);
if(lowerDepth != 0){
return lowerDepth;
}
lowerDepth = findDepth(t->right, value, depth+1);
return lowerDepth;
}
int countDeep( BinaryNode * t, int k ){
int count = 0;
if (t != nullptr){
countDeep( t->left, k );
if (findDepth(t, t->element, 0)){
count++;
}
countDeep( t->right, k );
}
return count;
}
Right now the function always returns 0 and I'm not quite sure why.
consider this:
int countDeep( BinaryNode * t, int k ){
int count = 0;
if (t != nullptr){
countDeep( t->left, k );
if (findDepth(t, t->element, 0)){
count++;
}
countDeep( t->right, k );
}
return count;
}
I didn't carefully read other code snippets, yet this function returns either 0 or 1. Because you discarded the return value of it in recursion. This function can be seen as pure function (although you modyfy the count through ++), so calling it without using its return value is wrong.
So if another function call this one, the count of the function only have one chance to self-increase, I didn't inspect into your code, maybe that "only chance" doesn't exist as well.

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

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.

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.

The Difference Between Calling and Returning a Recursive Function in C++

Can someone please explain with a simple example what precisely is the difference between calling and returning a recursive function in c++?
Here is my code which seeks to find a character in a string recursively. It works fine when I just call find(); the function displays an integer value, But, when I code return find(letter,word), it gives the correct result as either a 1 or 0. Thanks
bool find(char f,string str)
{
static int len = str.length() - 1;
static int count = 1;
if (len<0)
{
return false;
}
else
{
if (str[len] == f)
{
return true;
}
else
{
len--;
return find(f, str);
}
}
}
You don't return the function you return the result of the call.
Here a basic example of recursion :
unsigned int factorial(unsigned int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
If we call the function with n == 2 the program will do:
1) factorial (2) => return 2 * factorial(1); // It calls factorial with n == 1, do the multiplication and then return the result.
2) factorial(1) => return 1 * factorial(0); // same here with n == 0
3) factorial(0) => return 1; // from here the program will come back from the calls with the results
4) factorial(1) => return 1 * 1; => return 1;
5) factorial(2) => return 2 * 1; => return 2;
Few other things : be aware that your code will only work once as you use static int len, and count is a useless variable.
The function signature indicates a return value, so you need to embed the function call in a return statement for a value to be returned by the function, especially when neither of the if-conditionals are true.
Consider the following code (a variant of what the OP provided):
#include <iostream>
using namespace std;
int find(char f,string str) {
static int len = str.length() - 1;
static int count = 1;
int temp = 0;
if (len < 0) {
cout << count << "\n";
return -99;
}
else
if ( str[len] == f) {
return len;
}
len--;
count++;
temp = find( f, str );
cout << temp << "\n";
return temp;
}
int main() {
char ch = 'z';
int res = find(ch,"I");
if (res < 0) {
cout << "Letter '" << ch << "' was not found";
}
return 0;
}
See demo
Note that find() has a return value of -99 when the letter is not found. That value is captured by temp in find() and the function then returns the value of temp.
Now, consider main() -- its signature also indicates a return value, although it is discarded. If you attempt to execute the code without returning some kind of an integer in main(), the execution will be flawed.
So, whether you use a function recursively or not, if the function's signature indicates a return value then you need to return a value of the expected type. Since find() may return -99 or the position of the found letter, when it executes it will evaluate as one of those two values which will be returned by means of the return statement.

Count nodes with specific number of children in a binary tree?

I have this challenging exercise I got from a book about c++, and i'm not sure how to tackle this problem.
I must define a function called treeNodeCount() which returns the number of nodes in a binary tree (easy enough), and I also have to define an overloaded function that takes an int(0,1, or 2) which represents the number of children, and the function should return the nodes that have that specific number of children.
treeNodeCount should both use a function called nodeCount(elemType root) to do the recursion necessary to count the nodes(so basically all the work).
challenge number one says that I can add a second parameter to nodeCount which takes the number of children for the nodes that we want to count.
Challenge number two says that we cannot use a second parameter (this is the tough part)
I was able to do challenge one and here is what I came up with:
template <class elemType>
int binaryTreeType<elemType>::nodeCount(nodeType<elemType> *p, int a ) const
{
if (p == NULL){
return 0;
}
else if (a == 0 && p->lLink == NULL && p->rLink == NULL){
return 1 + nodeCount(p->lLink, a) + nodeCount(p->rLink, a);
}
else if (a == 1 && (p->lLink != NULL ^ p->rLink != NULL)){
return 1 + nodeCount(p->lLink, a) + nodeCount(p->rLink, a);
}
else if (a == 2 && p->lLink != NULL && p->rLink != NULL){
return 1 + nodeCount(p->lLink, a) + nodeCount(p->rLink, a);
}
else if (a == -1){
return nodeCount(p->lLink, a) + nodeCount(p->rLink, a) + 1;
}
return nodeCount(p->lLink, a) + nodeCount(p->rLink, a);
}
template <class elemType>
int binaryTreeType<elemType>::treeNodeCount(int a) const{
return nodeCount(root, a);
}
This seems to work fine but i am convinced that there has to be a better way.
I was not able to do challenge 2 though, and i have no idea what to do (is it even possible)
You can scrunch down your logic and make it a bit more straightforward by implementing a function to return the number of children given a node.
template <class elemType>
int nodeSize(nodeType<elemType>* node) const
{
int count = 0;
if (node->lLink)
++count;
if (node->rLink)
++count;
return count;
}
template <class elemType>
int binaryTreeType<elemType>::nodeCount(nodeType<elemType>* node, int count) const
{
if (node)
{
if (nodeSize(node) == count || count == -1)
return nodeCount(node->lLink, count) + nodeCount(node->rLink, count) + 1;
return nodeCount(node->lLink, count) + nodeCount(node->rLink, count);
}
return 0;
}
For the second challenge, you need a stack to avoid recursion.
template <class elemType>
int binaryTreeType<elemType>::treeNodeCount(int count) const
{
stack<nodeType<elemType>*> node_stack;
node_stack.push(root);
int num_matches = 0;
while (!stack.empty())
{
nodeType<elemType>* node = node_stack.top();
node_stack.pop();
if (node)
{
if (nodeSize(node) == count || count == -1)
++num_matches;
node_stack.push(node->lLink);
node_stack.push(node->rLink);
}
}
return num_matches;
}
Edit: fixed a goof in the above recursive version. Thanks to David Rodriguez for pointing it out.