二进制搜索不适用于n = 1,2

时间:2016-03-04 07:03:54

标签: c++ search binary-search

这是我的二进制搜索代码,n = no of elements in array

// Binary Search
// BUG: not working for n = 2

#include <iostream>

int main() {

    const int n = 1;
    int newlist[n];

    std::cout << "Enter " << n;
    std::cout << " elements in increasing order:\n";

    for( int i = 0; i < n; ++i ) {
        std::cin >> newlist[i];
    }

    int pos = 0, num;
    std::cout << "Enter number:\n";
    std::cin >> num;
    std::cout << '\n';


    int imin = 0, imax = n-1;
    int imid = (n - 1)/2;

    for( int i = 0; i < n; ++i ) {

        imid = (imin + imax) / 2;

        if( newlist[imid] == num ) {
            pos = imid;
        }

        else if( newlist[imid] < num ) {
            imin = imid+1;
        }

        else {
            imax = imid-1;
        }
    }

    if( pos != 0 ) {
        std::cout << "Found at " << pos+1;
    }

    else {
        std::cout << "Not found!\n";
    }

    return 0;
}

它适用于n > 2,但无法为n <= 2提供正确的输出,即即使对于找到的元素也会提供Not found!输出。

我认为一种方法是为n <= 2单独实现,但这将变得很麻烦!请帮忙。

3 个答案:

答案 0 :(得分:3)

将pos运算符设置为-1而不是0. 0代表您的第一个索引,并且由于您输出的元素未找到pos == 0条件,因此您的代码失败。您应该首先将pos设置为-1,并检查自身是否为未找到条件,如果在pos = 0处找到元素,则表示该元素存在于第一个索引处。

答案 1 :(得分:3)

等于pos的第一个0是正确的值。因此,在开始时将pos设置为-1,并在检查是否找到时-1(或更常见的>= 0)进行比较。

其次,应该更改的项目很少,因为现在它没有那么多二进制搜索:

  1. 没有理由在循环之前初始化mid,它只是临时变量,其范围在循环块中。
  2. 退出搜索的条件为min > max,您不需要任何其他计数器,因为即使值不存在,它也会始终n次运行循环。因此,请更改为while (min <= max) { ...
  3. 最后但并非最不重要的是,一旦找到该项目,请立即通过break声明退出循环。

答案 2 :(得分:3)

我不认为for循环是这里的控制结构,因为你想要在你找到正确的项目或imin和imax是非感性的时候完成。< / p>

在给出的实现中,当您找到项目并且只确认找到的项目时,您甚至不会停止循环&#34; n-(找到项目之前的迭代次数)&#34;次。

此外,C ++数组和向量基于0,位置== 0作为&#34;未找到&#34;的标记。是个坏主意;你可以使用http://en.cppreference.com/w/cpp/types/numeric_limits或n中的项目(因为索引从0到n-1)。

理论上,你可以使用指针算法使你的数组​​基于1,我假设你没有;我不推荐它。但是,您修改的代码缺少列表的实际定义。