【问题标题】:Where does log(n) come from in the O(N) notationO(N) 表示法中的 log(n) 来自哪里
【发布时间】:2011-10-12 21:44:15
【问题描述】:

我知道什么是 O(n) 表示法,并且我也了解如何获得 O(n)、O(n2)、...等表示法。

  • O(n) 意味着我必须通过序列一次
  • O(n2) 表示我有两个嵌套循环遍历序列

但是我如何获得 log(N)?

P.S.:我知道 Collections API 和一些具有 O(n log n) 遍历时间的类。我需要一个简单的解释。

【问题讨论】:

标签: algorithm programming-languages big-o


【解决方案1】:

lg N 出现在分治算法中,您可以迭代或递归地跳过 N 个项目集合中的一半数据。 Binary search 是典型的例子。二叉搜索树的插入、查找和删除操作也是O(lg N)。

迭代地丢弃一半的元素,从直觉上看,是迭代地加倍元素数量的逆过程。加倍会在 N 次迭代中产生 O(2^N) 个元素。请注意,N 的二进制对数是 2 次幂 N 的倒数。

可以通过合并排序等算法在 O(N lg N) 中对数组进行排序,但在概念上也更简单:遍历数组并将元素放入二叉搜索树。每个插入需要 O(lg N) 并且有 N 个,因此算法运行在 O(N lg N)。

(如果树是balanced,则按 BST 排序甚至具有最坏情况 O(N lg N) 复杂度。)

【讨论】:

  • 确切地说“比较排序”只能在 O(n Log n) 中完成,如果你抛开这个限制,你可以在 O(n) 中对数组进行排序。
【解决方案2】:

我认为最好的例子 N*log(N) 是查看基于比较的搜索:

我们以merge-sort 为例。

该算法采用一个元素数组,递归地将其拆分为 2,直到它得到一个长度为 2 的数组,然后在 O(n) 处合并这些片段,每个合并排序数组更容易。

好的,这是一个简单的描述,现在让我们看看它是什么样子的:

  [ 1 2 3 4 5 6 7 8 ]  
           |  
           /\  
  [1 2 3 4]  [ 5 6 7 8 ]
      |             |
      /\            /\
[1 2 ] [ 3 4]   [5 6] [7 8]

我希望你能在这里看到,递归的 深度 是 log(n)(因为它是一棵有 2 个分支的树……所以它是 log(n),基数为 2 )
但是在树的每个 level 中都有 O(n) 次操作(因为我们正在积极地重新排列 n 个对象)。

所以这里有 N*log(N) 复杂度。

大多数具有 Log(N) 复杂度的算法都是从基于树的算法中获得的。
有一些只是概率 log(n)(这意味着经过长时间的数学计算后,您会得到平均而言,它会类似于 log(n))

【讨论】:

    【解决方案3】:

    复杂度为 O(log n) 的典型算法是在有序数组中进行二分查找。而不是逐个遍历每个元素 O(n) 您迭代地将数组分成两半,并且只查看您知道元素可以存在的那一半。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-12
      • 2014-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      相关资源
      最近更新 更多