动态数组是一个数组,当一个元素被添加到一个已经完整的数组时,它将它的大小加倍,将现有元素复制到一个新的地方more details here。很明显,将有ceil(log(n))
批量复制操作。
在教科书中,我看到以这种方式计算的运动次数M
:
M=sum for {i=1} to {ceil(log(n))} of i*n/{2^i}
的论点是“一半元素移动一次,四分之一元素移动两次”......
但是我认为对于每个批量复制操作,复制/移动元素的数量实际上是n/2^i
,因为每个批量操作都是通过达到和超过2^i th
元素来触发的,因此运动是
M=sum for {i=1} to {ceil(log(n))} of n/{2^i}
(对于n = 8,它似乎是正确的公式)。
另一个论点谁是对的,哪个错了?
答案 0 :(得分:3)
两个版本都是 O(n),所以没有太大区别。
教科书版本将每个元素的初始写入计为移动操作,但不考虑第一个元素,它将移动ceil(log(n))
次。除此之外,它们是等价的,即
(sum for {i=1} to {ceil(log(n))} of i*n/{2^i}) - (n - 1) + ceil(log(n))
== sum for {i=1} to {ceil(log(n))} of n/{2^i}
当n
是2的幂时,当n
不是2的幂时,两者都会以不同的数量关闭。