最近幾年,計算機工做愈加難找,你必須比其餘人瞭解的更多,纔能有更多的機會找到一個更好的工做。html
C++ 標準庫(STL)是不少C++面試中都會問到的問題,不少不少問題會關於 Vector 的空間分配、動態增加之類的問題,那麼你瞭解 STL 中那些順序容器的區別與聯繫嗎? 你知道在什麼狀況選用什麼容器嗎?面試
先說結論,通常狀況選擇 vector
是很好的選擇,若是你的程序目標有以下特色時,纔可能須要換用別的容器:數組
全部的順序容器都具備能夠快速按順序訪問元素的能力,但每種容器在具體的實現上又有些區別。函數
順序容器類型 | 含義 | 特色 |
---|---|---|
vector | 可變大小數組 | 隨機訪問快、尾部插入元素快、其餘位置插入、刪除元素慢 |
deque | 雙端隊列 | 隨機訪問快、頭尾插入元素快 |
list | 雙向鏈表 | 只支持雙向順序訪問、在任何位置插入、刪除元素都很快 |
forward_list | 單向鏈表 | 只支持從前日後的單向順序訪問、在任何位置插入刪除元素都很快 |
array | 固定大小數組 | 隨機訪問快、容器大小固定不支持插入刪除元素 |
string | 字符串,相似vector,專門保存字符、隨機訪問快、在尾部插入刪除元素快 |
vector 和 string 將元素保存在連續的內存空間中,分配一段連續的內存空間進行存儲,其迭代器採用 C++ 指針便可,所以其支持隨機訪問和存儲,支持下標操做符,節省空間。可是其在分配的內存不夠的狀況下,須要對容器總體進行從新分配、拷貝和釋放等操做(空間的動態增加),並且在 vector 和 string 中間插入或刪除元素效率很低。性能
vector的內存分配實現原理:STL內部實現時,首先分配一個很是大的內存空間預備進行存儲,即capacity()函數返回的大小,當超過此分配的空間時再總體從新放分配一塊內存存儲(VS6.0是兩倍,VS2005是1.5倍),因此這給人以vector能夠不指定vector即一個連續內存的大小的感受。一般此默認的內存分配能完成大部分狀況下的存儲。.net
擴充空間(不論多大)都應該這樣作:指針
list 和 forward_list 是以節點形式來存放數據,使用的是非連續的內存空間來存放數據,所以,在其內部插入和刪除元素的時間複雜度都是O(1),可是其不支持隨機訪問和存取,不支持下標;由於每一個結點須要額外空間存儲鏈接的狀況,他們比 vector 佔用的內存要多不少。code
list 是非連續存儲結構,具備雙鏈表結構,每一個元素維護一對前向和後向指針,所以支持前向/後向遍歷。支持高效的隨機插入/刪除操做,但隨機訪問效率低下,且因爲須要額外維護指針,開銷也比較大。每個結點都包括一個信息快Info、一個前驅指針Pre、一個後驅指針Post。能夠不分配必須的內存大小方便的進行添加和刪除操做。使用的是非連續的內存空間進行存儲。cdn
forward_list 底層實現上是單鏈表,且實質上無任何多餘開銷,與 list 相比,此容器在不須要雙向迭代時提供更有效地利用空間的存儲。在鏈表內或跨數個鏈表添加、移除和移動元素,不會非法化當前指代鏈表中其餘元素的迭代器。forward_list 的迭代器不支持iter--
操做,即不支持反向迭代;同時 forward_list 也不支持size()
操做。htm
vector是一個單向開口的容器,deque則是一個雙向開口的容器,所謂雙向開口就是再頭尾兩端都可以作元素的插入和刪除操做。
deque 在空間增加上與 vector 不一樣,它是動態的以分段的連續空間組合而成,隨時能夠增長一段空間鏈接起來。 所以,爲了管理多段鏈接,deque有中控器的概念,此處實現上詳細狀況的請參見《STL源碼剖析》
array 與內置數組相似,大小是固定的,所以不支持增長元素、刪除元素以及改變容器大小的功能。 在使用 array 時,必須同時指定元素類型和大小array<int,20>
此容器是一個聚合類型,其語義等同於保有一個 C 風格數組 T[N] 做爲其惟一非靜態數據成員的結構體。該結構體結合了 C 風格數組的性能、可訪問性與容器的優勢,好比可獲取大小、支持賦值、隨機訪問迭代器等。
迭代器的範圍都是左開右閉,理解爲數學上的區間則是 [xx.begin(), xx.end())
,左邊是能夠達到的,右邊是達不到的。