使用<二进制搜索与使用< =

时间:2017-05-28 19:51:38

标签: java algorithm binary-search

在二进制搜索中,我们通常有低变量和高变量,通常有一个while循环测试低< =高,如此代码(来自维基百科)所示:

int SortedArray[max] = {....}

int BinarySearch (int key)
{
    int start = 0;
    int end = max - 1;
    int mid;
    while (start <= end)
    {
        mid = (start + end) / 2;
        if (key == a[mid])
            return mid;
        else if (key < a[mid])
            end = mid - 1;
        else start = mid + 1;
    }
    return -1;
}

在学习二元搜索时,我总是被教导低等高的方法,但是当看到其他实现时,我已经看到很多人在做(低/高)。

一个与另一个相比有优势吗?在我自己的原生实现中,我执行&lt; =方法但是当我将其切换为&lt;时,搜索失败。

使用一个与另一个是否有经验法则吗?

2 个答案:

答案 0 :(得分:6)

即使你的问题可能不是很清楚,我也可以推断你在谈论二元搜索的这种实现(这里是C,来自维基百科):

int SortedArray[max] = {....}

int BinarySearch (int key)
{
    int start = 0;
    int end = max - 1;
    int mid;
    while (start <= end)
    {
        mid = (start + end) / 2;
        if (key == a[mid])
            return mid;
        else if (key < a[mid])
            end = mid - 1;
        else start = mid + 1;
    }
    return -1;
}

如果您将start <= end替换为start < end,则会出现您的算法无法给出正确答案的情况。

让我们考虑两个案例。

1 - 您想在列表[1]中搜索1。在这种情况下,如果更改循环条件,start = 0, end = 0和算法将返回-1。

2 - 您想在列表[1, 2]中搜索2。在这种情况下,start = 0,end = 1.算法将在C中设置mid = (0+1)/2=0arr[mid] < key。这将start = 1, end = 1。同样,如果你在这里停止循环,算法将返回-1而不是1.

可能还有很多其他的例子。

度过愉快的一天

答案 1 :(得分:1)

对于low <= highhigh被视为包含high是我们考虑范围的一部分。)

对于low < highhigh被视为独占high不属于我们考虑范围的一部分。)

两者都可以是正确的,但其余代码会有细微的差别,特别是high初始化的方式(high = length-1high = length)以及如何更新({{ 1}}与high = mid-1)。

哪一个更好?

主要区别在于high = mid对于每种情况都会略有不同。

更具体地说,mid = (low + high) / 2在排他性情况下会更大1,因此,当high在包容性情况下,high-low将保持不变,但{{1}时在包容性情况下是奇数,mid在独占情况下将是1个元素更大(这是因为四舍五入)。

让我们考虑一个例子:

high-low

正如你所看到的,当没有单个中间元素时,一个将选择左边的元素,另一个将选择右边的元素。

虽然这有时会使一个更快,有时会使另一个更快,但平均运行时间将完全相同。

从可读性的角度来看,在我看来,使用基于0的数组的语言中的独占语言和基于1的数组的语言中的任何一个可能稍微好一点,以便最小化{{ 1}}在代码中。也可以争论只是坚持所有语言的单一版本,不要求人们理解这两个版本或在两者之间混淆。