我注意到实现动态数组非常常见(特别是在面试问题和家庭作业中);通常情况下,我将问题看作是:
在完整
时实现一个加倍容量的数组
或类似的东西。他们几乎总是(根据我的经验)明确使用 double 这个词,而不是更通用的
在完整
时实施一个增加容量的数组
我的问题是,为什么加倍?我理解为什么使用常量值是一个坏主意(感谢this question)但似乎使用更大的倍数而不是双倍更有意义;为什么不将容量增加三倍,或者将容量增加四倍,或将其平方?
要说清楚,我不是要求如何来加倍数组的容量,我问为什么加倍是惯例。
答案 0 :(得分:3)
是的,这是常见做法。
加倍是管理记忆的好方法。堆管理算法通常基于经典的Buddy系统,它是处理寻址和合并以及其他挑战的简单方法。知道这一点,在处理分配时坚持使用2的倍数是好的(尽管有混合算法,比如slab分配器,以帮助分段,所以它不像以前那样重要使用倍数)。 / p>
Knuth在他的一本书中介绍了我的遗嘱,但忘了标题。
请参阅http://en.wikipedia.org/wiki/Buddy_memory_allocation
将数组大小加倍的另一个原因是增加成本。您不希望每个Add()操作都触发重新分配调用。如果你已经填充了N个插槽,那么你很可能需要N的多个,历史是未来需求的一个很好的指标,所以对象需要“毕业”到下一个竞技场大小。通过加倍,重新分配的频率以对数方式下降(Log N)。加倍只是最方便的倍数(作为最小的整数乘数,它比3 * N或4 * N更具内存效率,而且它倾向于密切关注堆内存管理模型)。
答案 1 :(得分:2)
加倍的原因是它反复将元素附加到摊销的O(1)
操作中。换句话说,追加n
元素需要O(n)
次。
更准确地说,增加任何乘法因子可实现这一目标,但加倍是一种常见的选择。 I've seen other choices, such as in increasing by a factor of 1.5
.