-5

My code is to find a value in AVL tree that is strictly higher than the value inputted. I have tried to use inorder traversal approach it got stuck at saving data to array

I'm trying to traverse my BST using recursion and also save data to an array for every recursion. The problem is that although I have already incremented my pos every time I save data, the data seems to be overridden, not as my expectation.

void TreeSet::inorderRec(AVLNode *root, int *arr, int pos) {
    if (root) {
        inorderRec(root->left, arr, pos);
        arr[pos++] = root->key;
        inorderRec(root->right, arr, pos + 1);
    }
}

int TreeSet::higher(int val) {
    // TODO
    AVLNode *temp = root;
    int *arr = new int[count];
    int pos = 0;
    if (root) {
        inorderRec(root, arr, pos);
        for (int i = 0; i < count; i++)
            if (arr[i] > val)
                return arr[i];
    }
    return -1;
}

I expected to get an array in order and to find the value I want

2 Answers2

0

If I understand your code correctly an override is expected:

void TreeSet::inorderRec(AVLNode *root, int *arr, int pos) {
    // lets be pos = 0
    if (root) {
       inorderRec(root->left, arr, pos); // call with pos = 0
       arr[pos++] = root->key;           // write to arr[0], then set pos = 1     
       inorderRec(root->right, arr, pos + 1); // call with pos = 2
    }
}

So the left most part of your tree allways writes to arr[0]. I would expect you only fill every second array with new values.

Maybe you want to use a pointer to pos?

void TreeSet::inorderRec(AVLNode *root, int *arr, int* pos) {
    // lets be pos = 0
    if (root) {
       inorderRec(root->left, arr, pos); // call with *pos = 0, pos is set to n
       arr[(*pos)++] = root->key;           // write to arr[n], then set *pos = n+1     
       *pos = *pos +1;
       inorderRec(root->right, arr, pos); // call with *pos = n+2
    }
}
  • 1
    This doesn't compile. `int` is not `int *` – Caleth Dec 21 '18 at 14:30
  • You have to derefernce the pointer. And you have to give it a the address of a pointer at callsite. Or you just use a reference: `int& pos`. –  Dec 21 '18 at 14:32
  • `inorderRec(root->right, arr, *pos + 1)` is wrong, because `*pos + 1` is an `int`, not an `int*`, and cannot be massaged to be correct, because you can't take the address of a temporary – Caleth Dec 21 '18 at 14:37
0

You need the changes to pos to propagate back up the call stack

// note that we pass pos by reference
void TreeSet::inorderRec(AVLNode *root, int *arr, int& pos) { 
    if (root) {
       inorderRec(root->left, arr, pos);
       arr[pos++] = root->key;               
       inorderRec(root->right, arr, pos);
    }
}

Or you can eliminate pos and just update arr

void TreeSet::inorderRec(AVLNode *root, int *& arr) { 
    if (root) {
       inorderRec(root->left, arr);
       *arr++ = root->key;               
       inorderRec(root->right, arr);
    }
}

Which generalises to any OutputIterator

template <typename OutputIterator>
void TreeSet::inorderRec(AVLNode *root, OutputIterator & it) { 
    if (root) {
       inorderRec(root->left, it);
       *it++ = root->key;               
       inorderRec(root->right, it);
    }
}
Caleth
  • 35,377
  • 2
  • 31
  • 53