0

I'm trying to build a recursive function which returns the address within a sorted array by comparing to the middle value and proceeding based on relative size. Should the value not be in the array, it is supposed to simply print NULL. Now the first part of the function works, however whenever a null is supposed to happen I get a segmentation fault. The code looks as follows:

#include <stdio.h> 

int *BinSearchRec(int arr[], int size, int n){
  if(n==arr[size/2]){
    return &arr[size/2];
  } 

  else if(n>arr[size/2]) {
    return(BinSearchRec(arr, size+size/2, n));
  }

  else if(n<arr[size/2]) {
    return(BinSearchRec(arr, size-size/2, n));
  }

  else{
    return NULL;                    
  }
 }

 main(){
    int numb[]={2,7,8,9};

 if((int)(BinSearchRec(numb, 4, 22)-numb)>=0)   {
    printf("Position: %d \n", (int)(BinSearchRec(numb, 4, 22)-numb)+1);
    }

     else{
       printf("NULL \n");
     }

  }
2
  • Your function returns and int * and you treat it like an int. Also NULL == 0 => NULL >= 0. Commented Jan 19, 2015 at 12:05
  • this seems wrong, you are adding size to size/2 which is larger then size and you reach out of your array eventaully Commented Jan 19, 2015 at 12:08

3 Answers 3

6

Your recursive calls are wrong. In the first case you claim that the size of the array is 50% larger than originally, and you're passing the pointer wrong (you should pass the second "half" of the array).

In both cases, the size of the "array" is always half of what the function received. And in the second case, you need to pass a pointer to the second half of the array.

Something like

else if(n>arr[size/2]) {
  return(BinSearchRec(arr + sizeof/2, size/2, n));
}

else if(n<arr[size/2]) {
  return(BinSearchRec(arr, size/2, n));
}

You're also treating the returned value from the function wrong. It's not a value, it's a pointer to the value, you need to treat it as such. And it's okay to subtract one pointer from another (related) pointer, it's called pointer arithmetics.

Sign up to request clarification or add additional context in comments.

1 Comment

There's a typo in your code. It should be return(BinSearchRec(arr + size/2, size/2, n));.
1

In addition to what others have said about not dividing the array properly and not using the return value correctly, your function is missing a termination condition.

In your code, the las else will never be reached, because the three preceding conditions cover all possibilities: n is either smaller than, equal to or greater than arr[size/2].

You should test whether your subarray actually has elements before you access and compare them. Here's a revision of your code:

int *BinSearchRec(int arr[], int size, int n)
{
    int m = size/2;

    if (size == 0) return NULL;
    if (n > arr[m]) return BinSearchRec(arr + m + 1, size - m - 1, n);
    if (n < arr[m]) return BinSearchRec(arr, m, n);

    return &arr[m];
}

And here's an example main that shows how you make use of the pointer that was returned. If the pointer is NULL, the number is not in the array and you cannot dereference the pointer.

int main()
{
    int numb[] = {2, 7, 8, 9};
    int n;

    for (n = 0; n < 15; n++) {
        int *p = BinSearchRec(numb, 4, n);

        if (p) {
            printf("%d: @%d\n", n, (int) (p - numb));
        } else {
            printf("%d: NULL\n", n);
        }
    }
    return 0;
}

Comments

0

Instead of using a single size, it is easier to reason with 2 indexes (left and right) delimiting the sub-array you are exploring. Modifying your code according to this approach gives:

#include <stdio.h> 
#include <stdlib.h>

int *BinSearchRec(int arr[], int left, int right, int n){
  if (left > right) 
    return NULL;

  int mid = (left + right) / 2;

  if(n == arr[mid])
    return &arr[mid];

  if(n > arr[mid])
    return BinSearchRec(arr, mid + 1, right, n);
  else
    return BinSearchRec(arr, left, mid - 1, n);
 }


int main(int argc, char *argv[]){
  int numb[] = {2,7,8,9};
  int *p = BinSearchRec(numb, 0, 3, 22);

  if (p) {
    printf("Position: %d \n", (int) (p - numb + 1));
  } else {
    printf("NULL \n");
  }
  return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.