开发者

Writing a recursive binary search in C

I've found the following code online,

int binary_search(int a[], int low, int high, int target) {
    if (high < low)
        return -1;
    int middle = (low + high)/2;
    if (target < a[middle])
        return binary_search(a, low, middle-1, target);
    else if (target > a[middle])
        return binary_search(a, middle+1, high, target);
    else if (target == a[middle])
        return middle;
}

My function has a specified prototype(meaning that it has a set number of arguments that cannot be altered) this is what I have so far

bool search(int value, int array[], int n) {
    if (array[n/2] == value)
        return 1; 
    else if (array[n/2] < value)
        return search(value, &array[n/2], (n)/2);
    else
        // how do I "return" the other half?
}

Does my implementation look correct so far? I can't seem to fig开发者_如何学Cure out how to implement the final else statement.


high and low represent the bounds of subarray in which continue the research. If you analyze the code you'll notice that if target is smaller that a[middle] you'll have to continue the research in the first half of the array (in fact it calls binary_search passing the same low bound but, as a superior bound, the actual middle-1). On the other side, if target is greater that a[middle] you'll have to continue the research in the second half of the array (from middle+1 to high). Of course, if target is equal to a[middle] you've finished.


The trick to writing a recursive anything:

  1. Figure out how it should end.
  2. Figure out how it should look one step before it ends.
  3. Figure out how it should look two steps before it ends, and how moving from #2 to #1 is exactly the same as moving from #3 to #2.

Step #1:

If the number at the beginning of the search range is the desired number, return true.

If the end of the search range is the same as the beginning of the search range, and the number in the search range is not the desired number, return false.

Step #2:

If the search range has a length of two, split it into two one element search ranges, and search the range that might contain the required number.

Step #3:

If the search range has a length of more than two, split it into two roughly equal search ranges, and search the range that might contain the required number.

(which combining the two would look like)

If the search range has a length of two or more elements, split it into two roughly equal ranges, check the highest (last) number in the "lower" range, if the number is equal to or less than that number, search the lower range; otherwise, search the higher range.

This technique will not return you an optimum solution unless you select an optimum way to solve the problem; however, it will return you a correct solution (provided you do not make any true blunders).

Now the code

bool search(int value int array[], int lowIndex, int highIndex) {
  if (array[lowIndex] == value) {
    return true;
  } else if (lowIndex == highIndex) {
    return false;
  }
  int middleIndex = lowIndex + highIndex / 2;
  if (array[middleIndex] <= value) {
     return search(value, array, lowIndex, middleIndex);
  } else {
     return search(value, array, middleIndex+1, highIndex);
  }
}

When reading code online, you have a big disadvantage. You don't do any of the above three steps, so you really have to go about solving the problem backwards. It is akin to saying, I have a solution, but now I have to figure out how someone else solved it (assuming that they didn't make any mistakes, and assuming that they had the exact same requirements as you).


The high and low variables represent the current range you are searching. You usually start with the beginning and end of the array, and then determine if the value is in the first or second half, or exactly in the middle. If it is in the middle, you return that point. If it is below the middle, you search again (recursively), but now only in the lower half. If it is above the middle, you search the upper half. And you repeat this, each time dividing up and narrowing the range. If you find the value, you return, otherwise, if the range is so narrow that it is empty (both low and end high indexes are the same), you didn't find it.


High and low are upper and lower bounds on the candidate indices of the array. In other words, they define the portion of the subarray in which it is possible for the search target to exist. Since the size of the subarray is cut in half each iteration, it is easy to see that the algorithm is O(log n).


return search(value, &array[(n)/2], (n)/2);

On your current code, first of all, n should not be in parentheses (it doesn't make a difference, but it confuses me).

Next up, if it's meant to be returning the index in the array, your code doesn't do that, it returns 1. Judging by the prototype, you might consider a non-recursive approach, but this can work fine if you add the right values on to each return.

You can figure out the other statement. Just draw a picture, figure out where the pointers should be, and code them up. Here's a start:

       new array if > n/2
         v-----------v
0, 1, 2, 3, 4, 5, 6, 7
         ^
        n/2

Actually, you probably don't want to be including your middle value. Finally, make sure to take in to account lists of length zero, one, two and three. And please write unit tests. This is probably one of the most often incorrectly implemented algorithms.


I have tried to resolve your problem and this below code is really work . But what is the condition to escape recursion if value that want to be searched not lies in array

if(value==a[size/2]) return size/2;

    if( value<a[size/2]) {
        search(a,size/2,value);
    } else if (value>a[size/2] && a[size/2]<a[(a.length-1)/2]) {
        search(a,size/2+size,value);
    } else {
        search(a,size/2+a.length-1,value);
    }


int * binSearch (int *arr,int size, int num2Search)
{

    if(size==1)
        return ((*arr==num2Search)?(arr):(NULL));

    if(*(arr+(size/2))<num2Search)
        return binSearch(arr+(size/2)+1,(size/2),num2Search);

    if(*(arr+(size/2))==num2Search)
        return (arr+(size/2));

    return binSearch(arr,(size/2),num2Search);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜