为什么这个算法是O(n ^ 2)

时间:2015-09-12 17:50:27

标签: big-o

function multiply(x, y)
  Input: Two n-bit integers x and y, where y ≥ 0 Output: Their product
  if y=0: return 0 
  z = multiply(x, ⌊y/2⌋) 
  if y is even:
    return 2z 
  else:
    return x + 2z

如我的问题所述,为什么这个函数是O(n ^ 2)?这是上述例子所属的书的解释:

  

它必须在n次递归调用后终止,因为在每次调用y时减半 - 也就是说,它的位数减少1。每个递归调用都需要这些操作:除以2(右移);奇数/偶数的测试(查找最后一位);乘以2(左移);并且可能是一个加法,总共O(n)位操作。因此,总时间是O(n ^ 2),就像之前一样。

由于左移和右移除2和乘法,我认为它会比O(n ^ 2)大..也许n ^ 3.

2 个答案:

答案 0 :(得分:2)

每个操作右移,测试,左移每个位占用固定的时间,因此每次递归完成O(n)次。请记住,O(3n)仍然是O(n)。

由于整个函数使用左移递归地应用于每个位,因此先前的O(n)步执行O(n)次,使得总复杂度为O(n ^ 2)。

答案 1 :(得分:1)

这是comp-sci教科书还是VLSI教科书?因为答案取决于操作的复杂性y == 0,y / 2,2z,x + 2z和“y是偶数”。

作为应用程序开发人员,我认为这些是常量时间操作,因此它们都是O(1)。乘法函数则是O(log(Y))或O(N),其中N是Y中的位数。同样的事情。因此,我得出结论,整个函数是O(N)。

现在,计算机工程师可能会争辩说y / 2需要移位N位,因此它是O(N)操作。可能有一些CPU以这种方式工作。请允许我暂时荒谬,并争辩说我可以为y == 0创建一个带O(N ^ 47)的实现,因此这个函数是O(N ^ 48)。 : - )

实际上,任何现代的N位处理器都会并行执行N位数的位移,因此它们实际上是O(1)。也许回到8088,情况并非如此,但任何现代设计都是如此。所以在实践中我认为这是O(N)而不是O(N ^ 2)