Hey there I’m using a binary search method to find a number in an array, and I’m getting a StackOverflow error when looking for a number other than the one in the middle.
Here is my code:
public static <T extends Comparable< ? super T>>
int find(T [] a, T x, int low, int high){
if(low>high)
throw new IllegalArgumentException();
int tmp = (high-low)/2;
if(a[tmp].compareTo(x)==0)
return tmp;
else if(a[tmp].compareTo(x)>0)
find(a,x,tmp,high);
else if(a[tmp].compareTo(x)<0)
find(a,x,low,tmp);
return -1;
}
Also, if I try to look for a number under tmp, it returns -1.
I feel like I’m missing something but can’t figure out what.
Thanks in advanced!
This is the problem:
You should be using
tmp + 1in the first case andtmp - 1in the second. Otherwise if you’ve got (say) low = 0, high = 1 then you’ll potentially end up perpetually calling with the same arguments;tmpwill end up being 0, and ifxis more thana[0]you’ll just callfind(a, x, 0, 1)again.That’s my gut feeling, anyway. You should really log what happens in terms of the low/high values being used – I’m sure you’ll see some sort of repetition before it croaks.
EDIT: You’ve also got the comparison round the wrong way.
a[tmp].compareTo(x)will return a value less than 0 ifa[tmp]is less thanx– i.e. you ought to look later in the array, not earlier.EDIT: Currently your “exit with -1” code is broken – you’ll only ever return -1 if
a[tmp].compareTo(x)returns a non-zero value which is neither above zero nor below zero. I challenge you to find such an integer 🙂 (It would also do it if compareTo were unstable, but that’s a separate issue…)One option is to detect if
high == low– at that point, if you haven’t hit the right value, you can return -1: