1

The recursive version of the binary search in the book:

int binarySearch(int[] array, int target) throws BSException { return int binarySearch(int[] array, int target) throws BSException { 
    return binarySearch(array, target, 0, array.length-1);
}

int binarySearch( int[] array, int target, int lower, int upper ) throws BSException {
    int center, range;

    range = upper - lower; 

    if( range < 0 ){
        throw new BSException("Limits reversed");
    } else if( range == 0 && array[lower] != target ){ 
        throw new BSException("Element not in array");
    }

    if( array[lower] > array[upper] ){
        throw new BSException("Array not sorted"); 
    }
    center = ((range)/2) + lower; 
    if( target == array[center] ){
        return center;
    } else if( target < array[center] ){
        return binarySearch( array, target, lower, center - 1 ); 
    } 
    else {
        return binarySearch( array, target, center + 1, upper ); 
    }
}

and the iterative version:

while( true ){
    range = upper - lower;

    if( range == 0 && array[lower] != target ){
        throw new BSException("Element not in array");
    }

About every other algorithm book, include TAOCP by Donald Knuth, Algorithm Design Manual, Programming Pearl, etc, has "valid case" of

while (low <= high) {
    // ...
}
return -1;  // not found

or a "not found" case of low > high:

if (low > high) return -1;   // not found

but the recursive and iterative algorithm in the book Programming Interviews Exposed used low > high (meaning range < 0) as BSException("Limits reversed") and low == high to check for "not found". Now, if range is in fact less than 0, then the program would have thrown the exception of BSException("Limits reversed") and never be able to report NotFound.

Consider the case of an array with just 2 elements, or the lower and upper only include 2 elements, say

lower is 0
upper is 1
center is (1-0)/2 + 0 = 0

Now, let's say target is less than array[center], then upper = center - 1 and is -1, while lower stays as 0. So we have upper < lower meaning range < 0 but the recursive algorithm reports it as BSException("Limits reversed") rather than NotFound, while the iterative doesn't see lower == upper and go further with upper as -1 and use array[upper] and have strange behavior?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • https://stackoverflow.com/questions/39416560/how-can-i-simplify-this-working-binary-search-code-in-c/39417165#39417165 – Matt Timmermans Aug 03 '19 at 20:11
  • Your code throws "limits reversed" in a lot of "not found" cases, and has unnecessary branches. – Matt Timmermans Aug 03 '19 at 20:18
  • it is code from the book. To put that into perspective: https://rosettacode.org/wiki/Binary_search – nonopolarity Aug 04 '19 at 01:14
  • You should test it. Try `binarySearch(new int[]{0,1},-1)` and `binarySearch(new int[0],1)`. Then get a new book. – Matt Timmermans Aug 04 '19 at 02:13
  • 1
    Also: I often ask people to write a binary search in programming interviews, so I can tell you that this line: `if( range == 0 && array[lower] != target )` means "I ran through some test cases. My search exploded. I'm not sure why, but this line fixes it". (except it doesn't completely fix it) If you see this in a book as something to emulate, you do really need a different book. – Matt Timmermans Aug 04 '19 at 02:22
  • I was asked to write a binary search recently... I used recursion, except iterative seems simpler... and using recursion, I think I forgot to write the exit clause to begin with, and I might have written `if (low >= high) return -1;` and should have used `>` instead. But that was the 3rd question he gave me and it was about 5 minutes left for the interview. I wonder the interviewer, holding the piece of paper of standard answer, whether he would send to the hiring committee that I couldn't even write binary search correctly, and when the iterative way is so simple, why I used recursion – nonopolarity Aug 04 '19 at 02:44
  • if it is a book and they have all the time in the world to write and to look at references, it'd be more expected that they give a good, correct solution. If it is an interviewee who hasn't written binary search for the past 10 years or 15 years, their code won't be as clean as the standard answer, which was refined again and again perhaps since 50 years ago to make it so simple and elegant. That I understand. It'd be surprising if the interviewee can come up with the cleanest solution in that 10 minute time frame – nonopolarity Aug 04 '19 at 02:54

1 Answers1

0

The basic premise of binary search is keep on computing as long as lower <= upper is met. It means (upper-lower) (in your example it is range) can't be negative. If it is negative (upper is less than lower) you stop processing and return -1 indicating Not found or throw exception (as in your example).

That Limits Reversed is not meaningful to the caller. So, change it to throw the exception Not found.

if (range < 0 || (range == 0 && array[lower] != target)) {
    throw new BSException("Element not in array");
}

However, there can be a case where the caller of this recursive function mistakenly interchanged the lower and the upper. In that case, it would say Not found instead of Limits reversed but, that's ok. Let the caller investigate and find the mistake in his code.

fiveelements
  • 3,649
  • 1
  • 17
  • 16
  • you said, "The basic premise of binary search is keep on computing till the time lower <= upper is met." I thought the basic premise of binary search is keep on computing till the time lower > upper is met, or in other words, the basic premise of binary search is keep on computing as long as lower <= upper – nonopolarity Aug 03 '19 at 18:00
  • @太極者無極而生 "The basic premise of binary search" is such a complex phrase for a grade school algorithm, specifically, "I am thinking of a number from 1 to 10" you guess, and I'll tell you higher, lower or correct. Binary Search is the process of guessing numbers amongst sorted values. – Elliott Frisch Aug 03 '19 at 18:04
  • @太極者無極而生 changed the phrase. We mean the same. – fiveelements Aug 03 '19 at 18:08