擴容特點:
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倍的增長方式可以更好的實現對內存的重復利用,因而更好。