C++ STL vector擴容原理分析


擴容特點:

  1)新增元素:vector通過一個連續的數組存放元素,如果集合已滿,在新增數據的時候,就要分配一塊更大的內存,將原來的數據復制過來,釋放之前的內存,在插入新增的元素;

  2)對vector的任何操作,一旦引起空間重新配置,指向原vector的所有迭代器就都失效了 ;

  3)初始時刻vector的capacity為0,插入第一個元素后capacity增加為1;

  4)不同的編譯器實現的擴容方式不一樣,VS2015中以1.5倍擴容,GCC以2倍擴容。

以成倍方式增長

  假定有 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二倍的方式擴容,或者以1.5倍的方式擴容。

  以2倍的方式擴容,導致下一次申請的內存必然大於之前分配內存的總和,導致之前分配的內存不能再被使用,所以最好倍增長因子設置為(1,2)之間。

  借用一張圖來說明2倍與1.5倍的區別:

  

總結

  1)vector在push_back以成倍增長可以在均攤后達到O(1)的事件復雜度,相對於增長指定大小的O(n)時間復雜度更好。

  2)為了防止申請內存的浪費,現在使用較多的有2倍與1.5倍的增長方式,而1.5倍的增長方式可以更好的實現對內存的重復利用,因而更好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM