使用迭代器的二叉搜索,为什么我们使用"(end - begin)/2"?

Binary search using iterators, why do we use "(end - begin)/2"?

本文关键字:end begin 我们 迭代器 搜索 为什么      更新时间:2023-10-16

我正在研究迭代器,已经花了3天时间弄清楚为什么要使用:

auto mid = text.begin() + (end - beg) / 2;

代码:

int main()
{
    vector<int> text{ 10,9,8,7,6,5,4,3,2,1 };
    int sought = 3;
    // text must be sorted
    // beg and end will denote the range we're searching
    auto beg = text.begin(), end = text.end();
    auto mid = text.begin() + (end - beg) / 2; // original midpoint
                                               // while there are still elements to look at and we haven't yet found sought
    while (mid != end && *mid != sought) {
        if (sought < *mid) // is the element we want in the first half?
            end = mid; // if so, adjust the range to ignore the second half
        else // the element we want is in the second half
            beg = mid + 1; // start looking with the element just after mid
        mid = beg + (end - beg) / 2;// new midpoint
    }
    system("pause");
}

为什么

auto mid = text.begin() + (end - beg) / 2;

而不是:

auto mid = text.begin() + text.size() / 2;

请帮忙。

这样做是为了避免在将两个非常大的整数相加时可能发生的溢出,其中相加结果可能会大于最大整数限制并产生奇怪的结果。

额外,额外-阅读所有关于它:几乎所有的二进制搜索和合并排序都是损坏的

来自博客:

So what's the best way to fix the bug? Here's one way:
 6:             int mid = low + ((high - low) / 2);
Probably faster, and arguably as clear is:
 6:             int mid = (low + high) >>> 1;
In C and C++ (where you don't have the >>> operator), you can do this:
 6:             mid = ((unsigned int)low + (unsigned int)high)) >> 1;

二进制搜索传统上是这样写的。这种形式的编写有助于程序员理解二进制搜索,因为在标准二进制搜索中只使用开始、结束和中间。

可以在循环之前使用size()而不是end-star,但必须在while循环中使用end-start,因为end-start会更改。为了保持一致性,应避免使用size()