我們知道,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)之間。
知乎上有這樣一段解釋:
vector擴容2倍與1 5倍
如果按2倍擴容,第n次擴容需要的空間恰好比前n 1擴容要求的空間總和要大,那麼即使在前n 1次分配空間都是連續排列的最好情況下,他們留下的空間也不足以分配給此次擴容。理想分配方案是是在第n次resize 的時候能復用之前n 1次釋放的記憶體,但選擇兩倍的增長比如像這樣 1,2,4,8,16,32,可...
vector 1 5倍擴容優於2倍擴容的原因
假設我們一開始申請了 16byte 的空間。當需要更多空間的時候,將首先申請 32byte,然後釋放掉之前的 16byte。這釋放掉的16byte 的空間就閒置在了記憶體中。當還需要更多空間的時候,你將首先申請 64byte,然後釋放掉之前的 32byte。這將在記憶體中留下乙個48byte 的閒置...
auto ptr為什麼不能做為vector的元素
昨天看effectve c 的時候,發現了auto ptr這個東西。由於我待過的公司都是用的老版c 裡智慧型指標什麼的完全沒有出現過,都是直接操作的原始指標。雖說我很少出錯,但是總歸還是不太安全。言歸正傳,說回auto ptr,這個東西一開始我也見過,但是當時在趕專案也就沒有怎麼上心,這回正好看到了...