【问题标题】:Trying to prove the complexity of binary search is O(log(n))试图证明二分查找的复杂度是 O(log(n))
【发布时间】:2013-05-29 18:58:24
【问题描述】:

我正在尝试证明二进制搜索的复杂性。在维基百科中说,最坏的情况是 log(n)。这意味着:

如果我有 16 个元素的数组,log(16) 为 4。我应该最多调用 4 次来查找数组中的元素。

我的java代码:

class Main{
      int search(int[] array, int number, int start, int end) {
            System.out.println("Method call");
            int half = (end - start) / 2;

            if (array[start + half] == number) {
                return array[start + half];
            }
            if (array[start + half] < number) {
                return search(array, number, start + half, end);
            } else {
                return search(array, number, start, end - half);
            }
        }

        public static void main(String[] args) {
            int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
            for (int i : array) {
                System.out.println(i);
                new Main().search(array, i, 0, array.length);
            }
        }
    }

创意代码:http://ideone.com/8Sll9n

输出为:

1
Method call
Method call
Method call
Method call
Method call
2
Method call
Method call
Method call
Method call
3
Method call
Method call
Method call
4
Method call
Method call
Method call
Method call
5
Method call
Method call
6
Method call
Method call
Method call
Method call
7
Method call
Method call
Method call
8
Method call
Method call
Method call
Method call
9
Method call
10
Method call
Method call
Method call
Method call
11
Method call
Method call
Method call
12
Method call
Method call
Method call
Method call
13
Method call
Method call
14
Method call
Method call
Method call
Method call
15
Method call
Method call
Method call
16
Method call
Method call
Method call
Method call

一切都很好,除了搜索 1。我有 5 个“方法调用”,这意味着 5 大于 log(16)。

我的假设是,我计算电话的次数可能是错误的。谁能告诉我哪里错了?

【问题讨论】:

  • @sanbhat: Log(16) 是 4,当使用基数 2 计算时。要在使用标准计算器或谷歌时转换为基数 2,求和然后除以所需的对数,即对数(16) / log(2) = 4
  • 出于复杂性目的,对数的底是无关紧要的。对于二分搜索,以 2 为底很直观,因为我们每一步都将间隔减半。另一方面,您并不能通过检查算法的实现方式来证明算法的复杂性。证明必须正式完成。
  • Big-O 表示法(基本上)忽略了常数因子。因此,例如,O(g(n)) = O(2.g(n)),或者等效于任何常数。您可能想给the Wikipedia page 通读一遍。
  • 和类似的 O(log(n)) = O(log(n)+1)

标签: java algorithm complexity-theory big-o binary-search


【解决方案1】:

对于n 大小的输入,二进制搜索的复杂度是 O(loga n),对于 a &gt; 1。该算法的本质表明a=2,因为在每次迭代中,搜索空间都会减半。

您提供的代码也可以正常工作。关于算法复杂性的混淆已经发生,因为您忽略了 Big-Oh 表示法中涉及的隐藏常数以表示复杂性。

声明f(n)= O(g(n)) 表示f(n) ≤ cg(n)。在您的情况下,您忘记确认此常量cc 可以大到 100000000000 或小到 0.000000001。这是与 Big-Oh 表示法相关的一个问题。对于许多实际目的,由于涉及非常大或非常小的常数,渐近更复杂的算法可能会执行渐近更简单的算法。

例如,算法 g = O(1000000000 n) 与算法 h = O(n2) 相比性能会很差, 对于n &lt; 1000000000

所以结论是,由于隐藏常数的参与,你不能简单地通过计算执行的指令数来证明算法的复杂性。你需要有严格的数学方法才能得到证明。

例如,对于输入大小n=10 执行 100 指令的算法 f 可能是,

O(n) 如果 c 为 10 使得 f(n) = O(10 n)

O(n2) 如果 c 是 1 使得 f(n) = O(1 n 2).

O(n3) 如果 c 是 0.1 使得 f(n) = O(0.1 n 3).

【讨论】:

    【解决方案2】:

    在大 O 表示法中,常数可以忽略不计,因为随着输入 N 的值增加,复杂度不会因常数因素而发生任何变化,变得可以忽略不计。

    在这里,在二进制搜索中,发生了 1 个额外的调用。即使你接了十亿个号码,它仍然最多是 1 个额外的电话。因此它变得可以忽略不计,你不需要计算。

    【讨论】:

      猜你喜欢
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多