繁体   English   中英

二进制搜索功能不起作用

[英]Binary search function not working

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

您的代码有几个问题。

  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

当我运行它时,我得到一个indexoutofboundsexception因为在这些行中:

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

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

关于StackOverflow它在这一行:

if(desired<pivot){
     binarySearch(array,low,pivot, desired);
}

在这里,您在递归调用中传递了完全相同的参数,因此,如果它进入if循环的此分支,它将继续调用递归调用,直到它们中的太多进入堆栈并且出现堆栈溢出错误为止

当阵列本身已经排序(按顺序)BinarySearch的使用,这是二分查找的基础,你已经做了排序的一部分。

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

  1. 您的问题主要在于: pivot ,您在此处使用元素作为索引
  2. 由于if (desired < pivot) ;包括应该忽略的mid

此外,您应该尝试使用low + (high-low) / 2来获取中间索引(当数组的大小足够大时low + high会炸毁int ),然后获取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;
    }
}

输出:

[1, 5, 6, 8, 9, 52, 74, 91]

-1
3

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

您还希望将左呼叫从lowm-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;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM