Tree using recursive programming

1

Given a tree and some integer k, verify if the sum of the right subtree is greater than the (sum of the left subtree * k) for each subtree.

The output should be a vector containing the node values for all nodes of the tree for which the above condition is true, sorted in ascending order.

Here is the code:

#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
  int info;
  node* right;
  node* left;
};
int sommatuttechiavi(node*& tree){
  if (tree == nullptr){
    return 0;
  }
  else{
    return tree->info + sommatuttechiavi(tree->left) + sommatuttechiavi(tree->right);
  }
}
int sommachiavidestra(node*& tree){
  if (tree == nullptr){
    return 0;
  }
  tree = tree->right;
  return sommatuttechiavi(tree);
}
int sommachiavisinistra(node*& tree){
  if (tree == nullptr){
    return 0;
  }
  tree = tree->left;
  return sommatuttechiavi(tree);
}
void insert(node*& tree, int info){
  if (tree==nullptr){
    tree = new node;
    tree->info = info;
    tree->left = nullptr;
    tree->right = nullptr;
  }
  else{
    if (tree->info > info){
        insert(tree->left, info);
    }
    else{
        insert(tree->right, info);
    }
  }
  return;
}
void checkpropety(node*& tree, vector<int>& isok, int k){
  if (tree==nullptr){
    return;
  }
  else{
    if ((sommachiavisinistra(tree)*k) < sommachiavidestra(tree)){
        isok.push_back(tree->info);
    }
    checkpropety(tree->left, isok, k);
    checkpropety(tree->right, isok, k);
    return;
  }
}
bool ordina(const int& asd, const int& dsa){
  if (asd < dsa){
    return true;
  }
  else{
    return false;
  }
}
int main(){
  vector<int> resultset;
  node* root = nullptr;
  int n, k;
  cin >> n;
  cin >> k;
  for (int i = 0; i < n; i++){
    int t;
    cin >> t;
    insert(root, t);
  }
  checkpropety(root, resultset, k);
  sort(resultset.begin(), resultset.end(), ordina);
  for (unsigned i = 0; i < resultset.size(); i++){
    if (i == resultset.size() - 1){
        cout << resultset[i];
    }else{
        cout << resultset[i] << ' ';
    }
  }
  return 0;
}

I tested the program a few time with Dr. Memory and it detects this errors:

Error #1: UNADDRESSABLE ACCESS: reading 0x00000008-0x0000000c 4 byte(s)
# 0 checkpropety               [{a lot of directory}\test_esame2.cpp:51]
# 1 checkpropety               [{a lot of directory}\test_esame2.cpp:58]
# 2 main                       [{a lot of directory}\test_esame2.cpp:82]

I checked this function all day with no result. Can someone help me?? Thanks in advance, and sorry for my bad english.

c++
recursion
tree
asked on Stack Overflow May 12, 2015 by w0nderwall • edited May 12, 2015 by AndyG

2 Answers

2

You might not want to pass tree as a reference to sommachiavisinistra and sommachiavidestra, since that will also modify the caller's version of tree. In checkpropety, it seems like by the time you get to the checkpropety(tree->left, isok, k) recursive call, tree will already be nullptr.

Side note: ordina should just take int arguments, not const int&. And it could be shortened to one line: return (asd < dsa);

answered on Stack Overflow May 12, 2015 by Jeff Ames • edited May 12, 2015 by Jeff Ames
1

Your summation functions are altering the tree:

int sommachiavidestra(node*& tree){
  if (tree == nullptr){
    return 0;
  }
  tree = tree->right;
  return sommatuttechiavi(tree);
}

will set the parameter to its own right subtree.

Since you recurse when checking the "property", you will reach a point where after (sommachiavisinistra(tree)*k) < sommachiavidestra(tree), tree is null, and you get an invalid read.

Do this instead:

int sommachiavidestra(const node* tree){
  if (tree == nullptr){
    return 0;
  }
  return sommatuttechiavi(tree->right);
}

and similarly for the left subtree.

There is also no reason for sommatuttechiavi or checkPropety to take a reference parameter.

answered on Stack Overflow May 12, 2015 by molbdnilo

User contributions licensed under CC BY-SA 3.0