如何找到二分查找算法的迭代次数?

Posted

技术标签:

【中文标题】如何找到二分查找算法的迭代次数?【英文标题】:How to find the number of iterations of binary search algorithm? 【发布时间】:2019-05-04 21:39:48 【问题描述】:

如何获得二分查找的迭代次数?

这是我的代码:

int main() 

    int target = 11;
    int N = 10;
    std::vector<int> index;
    int num;

    for (int i = 0; i < N; i++) 
        index.push_back(i);
    

    int counter = 0;
    unsigned int M, L = (unsigned int)-1, R = N;

    M = (R - L) / 2;  // Assume N is not zero

    do 
        int value;
        M = M + L;
        value = index[M];
        if (value < target) L = M; else R = M;
        M = (R - L) / 2;
        counter++;
     while (M);  // M is the size of the current interval

    std::cout << R << '\n';
    std::cout << "counter: " << counter << '\n';

    system("pause");

    return 0;

我想知道取决于N 的迭代次数。 我知道这个算法是如何工作的,但我想要迭代次数 用数学表示。

【问题讨论】:

既然你知道算法是如何工作的,你就知道每次迭代都会将搜索区域减半。您可以执行连续除法,直到使用各种输入 N 到达 1 的搜索区域,绘制 N 与迭代次数的关系并选择最适合的曲线,或者您可以通过已经知道来缩短曲线拟合步骤哪个数学运算执行连续除法 【参考方案1】:

我会通过使用递归二进制搜索函数来进行递归增量。 在二进制检查的每个分支中,只需递增 1 即可递归计算迭代次数。

See live here

#include <iostream>
#include <vector>

std::size_t binarySearch(
    const std::vector<int>& arr,        // pass array as non-modifiyable(const ref)
    std::size_t start, std::size_t end, // start and end indexes of the array
    const int target)                   // target to find

    if (arr.size() == 1) return arr[0] == target ? 1 : 0; // edge case

    if (start <= end)
    
        const std::size_t mid_index = start + ((end - start) / 2);
        return arr[mid_index] == target ? 1 :                         // found the middle element
               arr[mid_index] < target ?
                 binarySearch(arr, mid_index + 1, end, target) + 1:   // target is greater than mid-element
                 binarySearch(arr, start, mid_index - 1, target) + 1; // target is less than mid-element
    
    return 0;


int main()

    int target = 11;
    const int N = 10;
    std::vector<int> index;
    index.reserve(N); // reserve some memory
    for (int i = 0; i < N; i++) 
        index.push_back(i);
    
    std::cout << "counter: " << binarySearch(index, 0, index.size() - 1, target) << std::endl;
    return 0;

输出

counter: 4

【讨论】:

【参考方案2】:

数学上可能的最大迭代次数(假设只有整数类型)是 = ceil( log2 ( initial_r - initial_l ) ) log 的基数是 2,因为每次我们通过取中间值并切换到其中一个来将我们的范围减半一半。

【讨论】:

如果可能的话,您能否举例说明这个想法?【参考方案3】:

我也一直试图围绕对数概念化,这就是我试图理解答案的方式

来自https://en.wikipedia.org/wiki/Binary_search_algorithm

在数学中,二进制对数 (log2n) 是 必须提高数字 2 才能获得值 n。也就是说,对于任何 实数 x, x=log2n 2x=n

&

每棵有 n 个叶子的二叉树的高度至少为 log2n,当 n 是 a > 2 的幂并且树是完全二叉树时相等。

二叉搜索有点像沿着二叉搜索树走,然后将节点减半,这个系列是对数(以 2 为底)系列 (我自己的理解,没有引用,可能有误)

然后来自https://www.cct.lsu.edu/~sidhanti/tutorials/data_structures/page305.html

高度为 h 的完美二叉树恰好有 2h+1-1 内部节点。相反,具有 n 的完美二叉树的高度 内部节点是 log2(n+1)。如果我们有一个搜索树 具有完美二叉树的形状,那么每个不成功的 搜索恰好访问 h+1 个内部节点,其中 h=log2(n+1).

(再次以我自己的理解继续跟进......) 因此,要到达节点 N(根据二叉搜索树的值为 N?),您将在最坏的情况下进行 log2(N+1) 次迭代(沿着树向下遍历那么多层)(发现仍然是一个概率,因此是“最坏情况”的措辞)。

在这里试运行(通过构建一个小的 BST 并手动计数):https://www.cs.usfca.edu/~galles/visualization/BST.html

(当然,因为我正在尝试整合不同的资源以达成在这种情况下有意义的理论,所以回答开放以供审查/确认/更正措辞/计算)

【讨论】:

以上是关于如何找到二分查找算法的迭代次数?的主要内容,如果未能解决你的问题,请参考以下文章

查找算法-Search,二分查找

二分查找算法(折半算法)

Task 04:数组二分查找

怎么计算java二分法查找的比较次数

二分查找法

二分查找算法算法指导 意境级讲解