二进制搜索功能不起作用

时间:2018-08-15 01:01:46

标签: java binary-search

我是Java的新手,刚刚开始学习一些简单的数据结构和算法。我一直在尝试实现二进制搜索功能,但是我一直收到堆栈溢出错误,而且我不知道它从哪里来。

public class BinarySearch {
    public static void main (String[]args){
        BinarySearch bs = new BinarySearch();

    int array [] = {1, 8, 6, 91, 52, 74, 5, 9};
    int length = array.length;
    bs.sort(array, 0, length-1);
    bs.print(array);
    System.out.println();
    System.out.println(bs.binarySearch(array, 0, length-1, 5));
}

public int binarySearch(int array [], int low, int high, int desired){
    int pivot = array[(low+high)/2];
    if(desired<pivot){
        binarySearch(array,low,pivot, desired);
    }else if(desired>pivot){
        binarySearch(array, pivot+1, high, desired);
    }else {
        return (low+high)/2;
    }
    // if element not present in array
    return -1;
}

4 个答案:

答案 0 :(得分:3)

您的代码有几个问题。

  1. 您不会返回递归调用的结果。添加return

    if(desired<pivot){
        return binarySearch(...);
    }else if(desired>pivot){
        return binarySearch(...);
    }
    
  2. 不要将要检查的索引与要检查的枢轴值混合在一起。计算索引并单独使用。另外,在重复出现低电平时,使用index - 1代替index作为high,以免将来考虑使用当前索引。

    int index = (low+high)/2;
    int pivot = array[index];
    
    if(desired<pivot){
        return binarySearch(array,low,index - 1, desired);
    }else if(desired>pivot){
        return binarySearch(array, index+1, high, desired);
    }else {
        return index;
    }
    
  3. 如果您的低值大于您的高值,则找不到该值。这是您的基本情况,不会在底部返回-1(无论如何现在是无法访问的代码,因为上面的每个逻辑分支都已返回一个值)。将其放在您当前的if上方。

    int index = (low+high)/2;
    int pivot = array[index];
    if (low > high)
        return -1;
    if ...
    

假设您的sort正常工作,以上更改应正确返回元素的索引;如果找不到,则返回-1

答案 1 :(得分:1)

运行此命令时,我得到indexoutofboundsexception,因为在这些行中:

int pivot = array[(low+high)/2];
if(desired<pivot){
   binarySearch(array,low,pivot, desired);
}

您将pivot作为最高点,可以是array中的任何数字。在此摘录的第一行中,您将称为high + low的索引,该索引可以是array中的任何数字加上您最初作为low传递的任何数字。因此,在此示例中,您可以调用0 + 92的{​​{1}}索引。

对于array,它在这一行:

StackOverflow

这里您在递归调用中传递了完全相同的参数,因此,如果它进入if(desired<pivot){ binarySearch(array,low,pivot, desired); } 循环的此分支,它将继续调用递归调用,直到它们中的太多进入堆栈为止堆栈溢出错误

答案 2 :(得分:1)

BinarySearch 用于已对数组本身进行排序(按顺序)的情况,这是 BinarySearch 的基础,并且您已经进行了排序部分。

但是,您的解决方案中存在两个明显的问题:

  1. 您的问题主要出在:pivot,您在此处使用元素作为索引
  2. mid之后应忽略if (desired < pivot)

此外,您应该尝试使用low + (high-low) / 2来获取中间索引(当数组的大小足够大时low + high会炸毁int),然后获取{ {1}}可以避免整数溢出,这也是获取中间索引的一种更好的做法。

pivot = array[mid]

输出:

public class BinarySearchBasic {
    public static void main(String[] args) {
        BinarySearchBasic bs = new BinarySearchBasic();

        int array[] = {1, 8, 6, 91, 52, 74, 5, 9};
        int length = array.length;
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
        System.out.println();
        System.out.println(bs.binarySearch(array, 0, length - 1, 5)); // miss;
        System.out.println(bs.binarySearch(array, 0, length - 1, 8)); // hit!
    }

    public int binarySearch(int array[], int low, int high, int desired) {
        int mid = low + (high - low) /2;
        int pivot = array[mid]; // get the middle element;
        if (desired < pivot) {
            binarySearch(array, low, mid - 1, desired); // since it's already smaller, use mid - 1 directly;
        } else if (desired > pivot) {
            binarySearch(array, mid + 1, high, desired); // same reason, use mid + 1 directly to skip mid;
        } else {
            return mid; // bingo!
        }
        return -1; // not found;
    }
}

答案 3 :(得分:1)

您没有基本情况。递归需要一个基本案例来知道何时停止递归。无限递归的结果是StackOverflowException,因为您正在调用且正在调用但未返回。您将要进行无限递归。二进制搜索的基本情况是hi小于lo时。

您还希望将左呼叫从low更改为m-1,而不是旋转,因为两端的边界都包含在内。

您还使用枢轴 VALUE 作为索引!而不是中间的 INDEX

binarySearch(array, low, pivot-1, desired);

应该是:

binarySearch(array, low, m-1, desired);

方法:

public int binarySearch(int array [], int low, int high, int desired) {

    // Not found
    if (high < low) 
        return -1;

    // Middle index
    int m = low + (high - low) / 2;

    // Middle value
    int pivot = array[m];

    if (desired < pivot)
        binarySearch(array, low, m-1, desired);

    else if (desired > pivot) 
        binarySearch(array, m+1, high, desired);

    else 
        return m;

}