由於程式設計時很難準確預知需要多少空間。比如申請了乙個定長的陣列存放資料,但是突然發現陣列填滿了,因此需要乙個更大的陣列來填放資料,這就涉及了陣列的自增策略問題。
定增策略
定增策略每次擴容將陣列長度增加定長。設我們需要乙個長為n
nn的陣列,陣列初始長度為i
ii,每次擴容的大小為i
ii,則n=(
m+1)
in=(m+1)i
n=(m+1
)i,m
mm為擴容次數。第一次擴容需要一塊2i2i
2i長度的陣列空間來存放新的陣列,此時,原陣列複製到新陣列空間需要o(i
)o(i)
o(i)
的時間。而當2i2i
2i長度的陣列再次用完後,又需要申請乙個長度為3i3i
3i的新陣列,並且再將長度為2i2i
2i的原陣列複製到新陣列,此時,需要的時間為o(2
i)
o(2i)
o(2i)。
若將申請空間的時間忽略不計,在使用定增策略時,我們每次擴容需要的時間代價分別為
i ,2
i,3i
,…,m
ii,2i,3i,…,mi
i,2i,3
i,…,
mi算術級數求和得:
總 時間
=i(m
+1)m
2總時間=\frac
總時間=2i
(m+1
)m由於n=(
m+1)
in=(m+1)i
n=(m+1
)i,i 為常
數i為常數
i為常數
,因此n
nn與m
mm同階。總時間
=n2−
ni2i
總時間=\frac
總時間=2i
n2−n
i,即得定增策略得到長度為n
nn的陣列的時間複雜度為o(n
2)
o(n^2)
o(n2
)。分攤到每個向陣列存放資料的操作時,分攤時間複雜度為o(n
)o(n)
o(n)
。倍增策略
倍增策略每次將當前長度翻倍,若我們需要乙個長度為n
nn的陣列,陣列長度初始為i
ii,每次擴容將陣列長度變成兩倍,則n=2
mi
n=2^mi
n=2mi,m
mm為擴容次數。同樣的,主要的時間會花費在將原陣列資料複製到新陣列的過程中。第一次花費i
ii,第二次花費2i2i
2i,每次乘2,以此類推。
同樣將申請空間的時間忽略不計,在使用倍增策略時,每次擴容需要的時間代價分別為
i ,2
i,4i
,8i,
…,2m
ii,2i,4i,8i,…,2^mi
i,2i,4
i,8i
,…,2
mi幾何級數求和得:
總 時間
=i(2
m−1)
=2mi
−i=n
−i
總時間=i(2^m-1)=2^mi-i=n-i
總時間=i(
2m−1
)=2m
i−i=
n−i
由於i
ii為常數,所以使用倍增策略時,得到長度為n
nn的陣列需要的時間複雜度為o(n
)o(n)
o(n)
。分攤到每個向陣列存放資料的操作時,分攤時間複雜度為o(1
)o(1)
o(1)
。裝填因子分析
定增策略中由於增量i
ii為常數,而不斷擴容時n
nn遠大於i
ii,所以定長策略的裝填因子無限接近100%。
倍增策略中最壞情況就是剛擴容就停止存入資料了,因此倍增策略中裝填因子大於50%。
有意思的是,倍增策略並不一定只能乘2,比如每次擴容都變成原陣列長度的1.5倍,那麼
i
,1.5i,
2.25i,
…,1.5
mi
i,1.5i,2.25i,…,1.5^mi
i,1.5i
,2.2
5i,…
,1.5
mi仍是幾何級數,此時總的時間複雜度還是o(n
)o(n)
o(n)
,分攤到每次存入資料的分攤時間複雜度仍為o(1
)o(1)
o(1)
,但是,1.5倍的倍增策略的裝填因子提高到了至少66.66%。需要注意的是,取到的倍數不能太接近1,也不能比1大太多,這樣才可以同時兼顧到時間和空間。
不同的動態陣列空間管理就是時間與空間的兌換,在考慮使用哪種策略時,要多考慮時間與空間的折衷方案。
01 複雜度分析與學習策略
從今天開始,邁過 資料結構和演算法 這道坎 1.面試 程式設計角度 1.1 通關大廠面試 1.2 日常業務中不再crud,提高 質量 有助於閱讀框架原始碼 背後設計思想。更好處理日常業務需求 1.3 更高的要求 追求,高手之間比內功 細節 2.個人角度 2.1 不被行業淘汰,不再原地踏步 2.2 對...
時間複雜度與空間複雜度的分析
演算法複雜度分為時間複雜度和空間複雜度 對於乙個演算法來說,空間複雜度和時間複雜度往往是相互影響的。當追求乙個較好的時間複雜度時,可能會使空間複雜度的效能變差,即可能導致占用較多的儲存空間 反之,當追求乙個較好的空間複雜度時,可能會使時間複雜度的效能變差,即可能導致占用較長的執行時間。有時我們可以用...
時間複雜度的分析
時間複雜度和空間複雜度是對演算法和 進行衡量的量。演算法分析主要是指分析演算法的效率,時間複雜度越 明 的利用效率就越高。時間複雜度有兩種計算方法 1.事後統計方法 在演算法關鍵位置插入計時器,演算法開始執行開啟計時器,終止時關閉計時器,最終經過計算的演算法執行時間的差值,可以計算出演算法利用效率。...