動態數組自增策略的複雜度分析

由於編程時很難準確預知需要多少空間。比如申請了一個定長的數組存放數據,但是突然發現數組填滿了,因此需要一個更大的數組來填放數據,這就涉及了數組的自增策略問題。

定增策略

定增策略每次擴容將數組長度增加定長。設我們需要一個長爲nn的數組,數組初始長度爲II,每次擴容的大小爲II,則n=(m+1)In=(m+1)I,mm爲擴容次數。第一次擴容需要一塊2I2I長度的數組空間來存放新的數組,此時,原數組複製到新數組空間需要O(I)O(I)的時間。而當2I2I長度的數組再次用完後,又需要申請一個長度爲3I3I的新數組,並且再將長度爲2I2I的原數組複製到新數組,此時,需要的時間爲O(2I)O(2I)

若將申請空間的時間忽略不計,在使用定增策略時,我們每次擴容需要的時間代價分別爲

I,2I,3I,,mII,2I,3I,…,mI

算術級數求和得:

=I(m+1)m2總時間=\frac{I(m+1)m}{2}

由於n=(m+1)In=(m+1)III爲常數,因此nnmm同階。=n2nI2I總時間=\frac{n^2-nI}{2I},即得定增策略得到長度爲nn的數組的時間複雜度爲O(n2)O(n^2)。分攤到每個向數組存放數據的操作時,分攤時間複雜度爲O(n)O(n)

倍增策略

倍增策略每次將當前長度翻倍,若我們需要一個長度爲nn的數組,數組長度初始爲II,每次擴容將數組長度變成兩倍,則n=2mIn=2^mImm爲擴容次數。同樣的,主要的時間會花費在將原數組數據複製到新數組的過程中。第一次花費II,第二次花費2I2I,每次乘2,以此類推。

同樣將申請空間的時間忽略不計,在使用倍增策略時,每次擴容需要的時間代價分別爲

I,2I,4I,8I,,2mII,2I,4I,8I,…,2^mI

幾何級數求和得:

=I(2m1)=2mII=nI總時間=I(2^m-1)=2^mI-I=n-I

由於II爲常數,所以使用倍增策略時,得到長度爲nn的數組需要的時間複雜度爲O(n)O(n)。分攤到每個向數組存放數據的操作時,分攤時間複雜度爲O(1)O(1)

裝填因子分析

定增策略中由於增量II爲常數,而不斷擴容時nn遠大於II,所以定長策略的裝填因子無限接近100%。

倍增策略中最壞情況就是剛擴容就停止存入數據了,因此倍增策略中裝填因子大於50%。

有意思的是,倍增策略並不一定只能乘2,比如每次擴容都變成原數組長度的1.5倍,那麼

I,1.5I,2.25I,,1.5mII,1.5I,2.25I,…,1.5^mI

仍是幾何級數,此時總的時間複雜度還是O(n)O(n),分攤到每次存入數據的分攤時間複雜度仍爲O(1)O(1),但是,1.5倍的倍增策略的裝填因子提高到了至少66.66%。需要注意的是,取到的倍數不能太接近1,也不能比1大太多,這樣纔可以同時兼顧到時間和空間。

不同的動態數組空間管理就是時間與空間的兌換,在考慮使用哪種策略時,要多考慮時間與空間的折衷方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章