C++中vector容器爲什麼擴容時按照2倍或者1.5倍進行擴容

擴容機制

首先在VS2013底下,vector的擴容操作是每次擴容*1.5;在GCC環境下是2倍。

  • GCC下的擴容方式是以二倍形式擴容。
    在這裏插入圖片描述
  • VS2013下是以1.5倍進行擴容
    在這裏插入圖片描述
    所以可能會有疑問:
  • 問題一:爲什麼非要以倍數的形式增長,而不是以個數的形式增長。
  • 問題二:爲什麼每次增長是1.5倍或者2倍形式,而不是3倍或者4倍形式增長。

詳解問題一

倍數方式空間拷貝數據次數

假設總共有n個元素,以m倍的形式增長。(比如現在舉例n=100, m=2),所以,vector的push_back的操作次數可以是logmN,也就是log2(100),換算下來大概是需要進行7次擴容。這樣的話,相當於舊空間數據到原空間數據的拷貝有7次。

個數方式空間拷貝數據次數

和倍數方式假設相同,n=100;這次m代表的是每次新空間的大小位n+m;m爲新空間新增大小,比如這次m爲10(每次新增10個空間)。所以這次的擴容次數爲 100/10 = 10次,也就是說,插入100白個元素,需要擴容10次。
但是,如果n=1000的情況下, 以個數形式進行擴容就不能在爲10了,否則拷貝空間次數將會太多
有的小夥伴要問:但是可以取100呀,想想,如果n=10的情況下,取100又不太合適,所以,以個數的形式來進行擴容顯然不符合所用n的取值。
所以在STL中vector以倍數的形式進行擴容

詳解問題二

如果以大於2倍的方式來進行擴容,下一次申請空間會大於之前申請所有空間的總和,這樣會導致之前的空間不能再被重複利用,這樣是很浪費空間的操作。所以,如果擴容一般基於(1, 2] 之間進行擴容

知乎上對於擴容機制的解釋

  • 當m=2時
    因爲每次擴容都滿足等比數列通項公式an = a1*q^(n-1) = 4*2^(n-1)
    而前n-1項的內存和爲Sn = a1*(1-q^(n-1))/(1-q) = 4*2^(n-1)-4
    所以第n項和前n-1和之間的差值爲an - Sn = 4,這也就說明,前n-1項不能夠完成第n項的空間重用。
  • 當m= 1.5時
    同樣的方法,計算出 an - Sn = 8 - 4*1.5^(n-1)
    所以,當n達到一定的值的時候,就可以利用內存分配的方式將之前的空間進行重用,所以一般情況下爲了使其爲整數,選用2倍或者1.5倍來進行擴容。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章