C++的STL模板庫中提供了3種容器類:vector,list,deque
vector - 會自動增長的數組
list - 擅長插入刪除的鏈表
deque - 擁有vector和list兩者優點的雙端隊列
- vector - 會自動增長的數組
vector又稱爲向量數組,他是爲了解決程序中定義的數組是
不能動態改變大小這個缺點而出現的。
由於程序自動管理數組的增長,對於我們程序員來說確實輕鬆了不少,
只管把數據往裏面插就行vector由於數組的增長只能向前,所以只提供了後端插入和後端刪除,
也就是push_back和pop_back。當然在前端和中間要操作數據也是可以的,
用insert和erase,但是前端和中間對數據進行操作必然會引起數據塊的移動,
這對性能影響是非常大的。對於所有數組來說,最大的優勢就是隨機訪問的能力。
在vector中,提供了at和[]運算符這兩個方法來進行隨機訪問。
由於每個數據大小相同,並且無間隔地排列在內存中,
所以要對某一個數據操作,只需要用一個表達式就能直接計算出地址:
address = base + index * datasize同樣,對vector進行內存開闢,初始化,清除都是不需要花大力氣的,
從頭到尾都只有一塊內存。 - list - 擅長插入刪除的鏈表
鏈表強悍的就是動態增長和刪除的能力。P
但對於數組強悍的隨機訪問能力來說的話,鏈表卻很弱。
list是一個雙向鏈表的實現。
爲了提供雙向遍歷的能力,list要比一般的數據單元多出兩個指向前後的指針。
這也是沒辦法的,畢竟現在的PC內存結構就是一個大數組,
鏈表要在不同的環境中實現自己的功能就需要花更多空間。
list提供了push_back,push_front,pop_back,pop_front四個方法
來方便操作list的兩端數據的增加和刪除,不過少了vector的at和[]運算符的
隨機訪問數據的方法。並不是不能實現,而是list的設計者
並不想讓list去做那些事情,因爲他們會做得非常差勁。
對於list來說,清除容器內所有的元素是一件苦力活,
因爲所有數據單元的內存都不連續,list只有一個一個遍歷來刪除。
- deque - 擁有vector和list兩者優點的雙端隊列
STL的deque的實現沒有怎麼去看過,不過根據我自己的猜測,
應該是把數組分段化,在分段的數組上添加指針來把所有段連在一起,
最終成爲一個大的數組。
deque和list一樣,提供了push_back,push_front,
pop_back,pop_front四個方法。可以想象,如果要對deque的兩端進行操作,
也就是要對第一段和最後一段的定長數組進行重新分配內存區,
由於分過段的數組很小,重新分配的開銷也就不會很大。
deque也和vector一樣,提供了at和[]運算符的方法。
要計算出某個數據的地址的話,雖然要比vector麻煩一點,
但效率要比list高多了。
首先和list一樣進行遍歷,每次遍歷的時候累積每段數組的大小,
當遍歷到某個段,而且baseN <= index < baseN + baseN_length的時候,
通過address = baseN + baseN_index就能計算出地址
由於分過段的後鏈表的長度也不是很長,所以遍歷對於
整體性能的影響就微乎其微了。