二进制搜索算法的正确方法

时间:2019-09-27 03:59:35

标签: java binary-search

我刚刚了解了二进制搜索算法,并尝试实现它。我使用了一些测试用例,它似乎工作正常。但是,当我检查GeeksforGeeks时,它们处理索引的方式有很多差异。任何人都可以阐明我的实施是否良好。如果没有,它将如何无法工作?

这是我的代码:

static int binarySearch(int arr[], int i, int r, int x) {

    if(r > 1) {
        int middle = r/2;

        if(arr[middle] == x) {
            return middle;
        }

        if(arr[middle] > x) {
            return binarySearch(arr, i, middle, x);
        }else {
            return binarySearch(arr, middle, r+1, x);
        }
    }       

    return -1;
}

1 个答案:

答案 0 :(得分:0)

假设我们的函数将对子数组arr[l..r](包括)进行二进制搜索。在这里,r - l + 1是此子数组的长度,当它不是正数(或r < l)时,我们没有有效的子数组,我们无法搜索任何内容,因此该函数停止递归并返回-1。

您知道,我们总是制作两个(几乎)相等长度的子数组。因此,middle = r/2是不正确的,而middle = (l + r) / 2是正确的。新的子数组是arr[l..middle-1]arr[middle+1..r]。我们在检查了子数组的中间元素后对其进行了划分,因此这两个子数组不应像您看到的那样包含中间索引。

现在,我们可以重写您的代码。

static int binarySearch(int arr[], int l, int r, int x) {
    if (r >= l) {
        int middle = (l + r) / 2; //int middle = l + (r - l) / 2; for avoiding integer overflow
        if(arr[middle] == x)
            return middle;
        if (arr[middle] > x)
            return binarySearch(arr, l, middle - 1, x);
        else
            return binarySearch(arr, middle + 1, r, x);
    }       
    return -1;
}

这是二进制搜索算法的非递归版本。通常,它可以稍微快一点。

static int binarySearch2(int arr[], int l, int r, int x) {
    while (r >= l) {
        int middle = (l + r) / 2; //int middle = l + (r - l) / 2; for avoiding integer overflow
        if (arr[middle] == x)
            return middle;
        if (arr[middle] > x)
            r = middle - 1;
        else
            l = middle + 1;
    }
    return -1;
}

在调用这些函数之前,请不要忘记对数组进行排序。 假设n是给定数组的长度。 对于基于0的数组,调用函数的正确形式是:

binarySearch(arr, 0, n - 1, x);

binarySearch2(arr, 0, n - 1, x);

对于基于1的数组,调用函数的正确形式是:

binarySearch(arr, 1, n, x);

binarySearch2(arr, 1, n, x);
相关问题