STL vector(四) vector 扩容为什么要以1.5倍或者2倍扩容

      我们知道,vector 在需要的时候会扩容,在 VS 下是 1.5倍,在 GCC 下是 2 倍。那么会产生两个问题:

(1)为什么是成倍增长,而不是每次增长一个固定大小的容量呢?

(2)为什么是以 2 倍或者 1.5 倍增长,而不是以 3 倍或者 4 倍等增长呢?

1、第一个问题 : 

      如果已成倍方式增长。假定有 n 个元素,倍增因子为 m; 完成这 n 个元素往一个 vector 中的 push_back​操作,需要重新分配内存的次数大约为 logm(n); 第 i 次重新分配将会导致复制 m^(i) (也就是当前的vector.size() 大小)个旧空间中元素; n 次 push_back 操作所花费的时间复制度为O(n),如下图所示:


                  

m / (m - 1),这是一个常量,均摊分析的方法可知,vector 中 push_back 操作的时间复杂度为常量时间.​
      如果一次增加固定值大小 。假定有 n 个元素,每次增加k个;第i次增加复制的数量为为:100i ;n 次 push_back 操作所花费的时间复杂度为O(n^2):
                       
均摊下来每次push_back 操作的时间复杂度为O(n);
总结:对比可以发现采用采用成倍方式扩容,可以保证常数的时间复杂度,而增加指定大小的容量只能达到O(n)的时间复杂度,因此,使用成倍的方式扩容。


2、第二个问题

      有人回答说:vector最关键在于查询,使用移位(2的幂)直接得到哈希链以及节点长度,然后相减直接得到键值,复杂度为O(2),性能近似于数组,插入删除可动态,这就是vector设计的基本目的。

      显然,增长的倍数不可能很大,也不会比 1 小,那么,它的最佳上限是多少呢?如果以 大于2 倍的方式扩容,下一次申请的内存会大于之前分配内存的总和,导致之前分配的内存不能再被使用。所以,最好的增长因子在 (1,2)之间。

      

知乎上有这样一段解释:

https://www.zhihu.com/question/36538542/answer/67929747


      当 k =1.5 时,在几次扩展以后,可以重用之前的内存空间了

猜你喜欢

转载自blog.csdn.net/dengheCSDN/article/details/78985684