2

I'm junior in C language and algorithms.

I try to use recursion for binary search and I can't understand how to check if number doesn't exist in array.

Here my code:

#include <stdio.h>

#define SIZE 15
#define midpoint(start, end) (start + end) / 2

void fill_array(int array[]);

int find(int target, int array[], int start, int end);

int main() {
    int array[SIZE];

    fill_array(array);
    return find(2, array, 0, SIZE);
}

void fill_array(int array[]) { //here I just fill array 
    for (int i = 0, number = 0; i <= SIZE; ++i) {
        array[i] = number++;
        number++;
    }
}

int find(int target, int array[], int start, int end) {
    int mid;
    mid = midpoint(start, end);

    if (target > array[mid]) {  
        find(target, array, mid + 1, end);
    }

    if (target < array[mid]) {
        find(target, array, start, mid - 1);
    }

    if (target == array[mid]) {
        printf("%d\n", mid);
    }
}

I want to return (-1) if number doesn't exist in array.

3
  • 3
    "I want to return (-1) ..." but find() misses any return statement. Commented Dec 18, 2016 at 12:19
  • 2
    i <= SIZE --> i < SIZE Commented Dec 18, 2016 at 12:20
  • Recursion termination condition is insufficient. Commented Dec 18, 2016 at 12:23

2 Answers 2

1

There are multiple issues in your code:

  • Defining midpoint() as a macro is error prone. Your definition is not properly parenthesized, it should read:

    #define midpoint(start, end) (((start) + (end)) / 2)
    

    Written as half the sum, it actually would invoke undefined behavior for large values of start and end, a much safer version would be start + (end - start) / 2, but should not be used in a macro as it evaluates start twice. Just write the code in the function directly.

  • Your initialization function iterates one step too far, the loop should read:

    for (int i = 0, number = 0; i < SIZE; i++) {
        array[i] = number;
        number += 2;
    }
    
  • find() should indeed return the index of the value found or -1 if not found. You do not return anything. make it return -1 upon failure and the value of the recursive call when recursing.

  • the arguments to find are start, the starting index of the range, included in the search, and end the upper bound, excluded from the search. You should not pass mid - 1 when recursing on the left part.

Here is a corrected version:

#include <stdio.h>

#define SIZE 15

void fill_array(int array[], int size) {
    // here I just fill array with even numbers
    for (int i = 0, number = 0; i < SIZE; i++) {
        array[i] = number;
        number += 2;
    }
}

int find(int target, const int array[], int start, int end) {
    if (start >= end) {
        // empty range: not found
        return -1;
    }

    int mid = start + (end - start) / 2;

    if (target == array[mid]) {
        return mid;
    }
    if (target > array[mid]) {  
        return find(target, array, mid + 1, end);
    } else {
        return find(target, array, start, mid);
    }
}

void locate(int value, const int array[], int size) {
    int res = find(value, array, 0, size);
    if (res < 0) {
        printf("%d was not found in the array\n", value);
    } else {
        printf("%d was found at offset %d\n", value, res);
    }
}

int main(void) {
    int array[SIZE];

    fill_array(array, SIZE);
    locate(1, array, SIZE);
    locate(2, array, SIZE);
    return 0;
}

Output:

1 was not found in the array
2 was found at offset 1

Note that find() can be implemented as a loop with less code:

int find(int target, const int array[], int start, int end) {
    while (start < end) {
        int mid = start + (end - start) / 2;

        if (target == array[mid]) {
            return mid;
        }
        if (target > array[mid]) {  
            start = mid + 1;
        } else {
            end = mid;
        }
    }
    return -1;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I have written a BinarySearch C code for you to inspect and see where is your problem. This part: int BinarySearch is doing BinarySearch via loops, This part: int BinarySearchRec is doing BinarySearch via recursion.

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

int BinarySearch(int*,int,int);
int BinarySearchRec(int*,int,int,int);
int main(void){
    int length;
    int searchElement;
    int* list;
    printf("Enter the length of the list\n");
    scanf("%d",&length);
    list = malloc(length*sizeof(int));
    printf("Enter the search element for this list");
    scanf("%d",&searchElement);
    printf("Enter the elements for this list\n");
    for(int i=0;i<length;i++){
        scanf("%d",list+i);
    }
    int result1 = BinarySearch(list,length,searchElement);
    int result2 = BinarySearchRec(list,0,length-1,searchElement);
    printf("Result from loopy BinarySearch : %d\n",result1);
    printf("Result from recursive BinarySearch: %d\n",result2);
    return 0;
}

int BinarySearch(int* list, int length, int searchElement){
    int found=0;
    int min = 0;
    int max = length-1;
    int mid=0;
    while(found != 1 && max > min){
        mid = (max+min)/2;
        if(searchElement == list[mid]){
            found = 1;
        }else if(searchElement > list[mid]){
            min = mid+1;
        }else if(searchElement < list[mid]){
            max = mid;
        }

    }
    if(max > min){
        return mid;
    } else{
        return -1;
    }
}

int BinarySearchRec(int* list,int min,int max,int searchElement){
    int mid = (min+max)/2;
    if(max > min){
        if(searchElement == list[mid]){
                    return mid;
            }else{
                    if(searchElement < list[mid]){
                             return BinarySearchRec(list,min,mid,searchElement);
                    }else if(searchElement > list[mid]){
                            min = mid+1;
                            return BinarySearchRec(list,mid+1,max,searchElement);
                    }
            }
    }else{
        return -1;
    }
}

1 Comment

This list = malloc(length* ...; ...; for(... i<length;... list+i); doesn't look good.

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.