尝试使用T数组中的二进制搜索方法递归查找数字时获取StackOverflowError

时间:2011-10-17 16:30:31

标签: java arrays recursion stack-overflow binary-search

嘿,我正在使用二进制搜索方法在数组中查找数字,并且在查找中间数字以外的数字时会收到StackOverflow错误。

这是我的代码:

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;
}

另外,如果我尝试在tmp下查找数字,则返回-1。 我觉得我错过了一些但却无法弄清楚是什么。 先谢谢!

3 个答案:

答案 0 :(得分:2)

这是问题所在:

if(a[tmp].compareTo(x)>0)
    find(a,x,tmp,high);
else if(a[tmp].compareTo(x)<0)
    find(a,x,low,tmp);

您应该在第一种情况下使用tmp + 1,在第二种情况下使用tmp - 1。否则,如果你有(比方说)low = 0,high = 1,那么你可能会使用相同的参数结束永久调用; tmp最终会为0,如果x超过a[0],您只需再次致电find(a, x, 0, 1)

无论如何,那是我的直觉。你应该记录下使用的低/高值时会发生什么 - 我相信你会在它呱呱叫之前看到某种重复。

编辑:你以错误的方式进行比较。如果a[tmp].compareTo(x)小于a[tmp]x将返回小于0的值 - 即您应该在数组中查看以后,而不是更早。

编辑:目前你的“退出-1”代码被破坏了 - 如果a[tmp].compareTo(x)返回一个既不高于零也不低于零的非零值,你只会返回-1。我挑战你找到这样一个整数:)(如果compareTo不稳定,它也会这样做,但这是一个单独的问题...)

一个选项是检测是否high == low - 此时,如果没有达到正确的值,则可以返回-1:

int comparison = a[tmp].compareTo(x); // Let's just compare once...
if (comparison == 0) {
   return tmp;
}
// This was our last chance!
if (high == low) {
   return -1;
}
// If a[tmp] was lower than x, look later in the array. If it was higher than
// x, look earlier in the array.
return comparison < 0 ? find(a, x, tmp + 1, high) : find(a, x, low, tmp - 1);

答案 1 :(得分:2)

你需要:

else if(a[tmp].compareTo(x)>0)
    find(a,x,tmp - 1,high);
else if(a[tmp].compareTo(x)<0)
    find(a,x,low,tmp + 1);

否则,当你有low = 0high = 1时,你基本上会以递归方式调用具有相同参数的函数。问题是你真的不需要再次查看mid处的元素,因为你已经知道它相对于你想要找到的值是大于还是小。

此外,如果IllegalArgumentException小于-1,则应返回high,而不是low

答案 2 :(得分:1)

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;//replaced - with + for average

    if(a[tmp].compareTo(x)==0)
        return tmp;
    else if(a[tmp].compareTo(x)>0)
        return find(a,x,tmp,high); //return the found index
    else if(a[tmp].compareTo(x)<0)
        return find(a,x,low,tmp);
    return -1;
}

如果tmp是高和低的平均值,则需要添加它们然后除以2

也会在递归调用中返回找到的值