基本參考 https://blog.csdn.net/qq_14898543/article/details/51381642
容器特性:
vector:典型的序列容器,C++標准嚴格要求次容器的實現內存必須是連續的,唯一可以和標准C兼容的stl容器,任意元素的讀取、修改具有常數時間復雜度,在序列尾部進行插入、刪除是常數時間復雜度,但在序列的頭部插入、刪除的時間復雜度是O(n),可以在任何位置插入新元素,有隨機訪問功能,插入刪除操作需要考慮。
deque(雙端隊列):序列容器,內存也是連續的,和vector相似,區別在於在序列的頭部插入和刪除操作也是常數時間復雜度,可以在任何位置插入新元素,有隨機訪問功能。
list :序列容器,內存是不連續的,任意元素的訪問、修改時間復雜度是O(n),插入、刪除操作是常數時間復雜度,可以在任何位置插入新元素。
set :關聯容器,元素不允許有重復,數據被組織成一棵紅黑樹,查找的速度非常快,時間復雜度是O(logN)
multiset:關聯容器,和set一樣,卻別是允許有重復的元素,具備時間復雜度O(logN)查找功能
map :關聯容器,按照{鍵,值}方式組成集合,按照鍵組織成一棵紅黑樹,查找的時間復雜度O(logN),其中鍵不允許重復。
multimap:和map一樣,區別是鍵可以重復
分類:
連續內存容器:vector、deque
所以有數據插入和刪除的時候,如果不是在序列的或者兩端那么花費的代價是非常大的,因為需要保證連續內存,同時給新元素騰出空間或者填充刪除元素的空間,如果存儲的是復雜結構的話就要花費大量的時間進行拷貝操作(可以存儲復雜結構的指針來彌補這個缺陷,這個討論在另個總結中進行)
基於節點的容器:list、set、multiset、map、multimap
這樣的容器在插入刪除元素的時候修改的只是節點的指針,這樣的消耗是非常小的。
考慮因素:
(1)需要大量添加元素:vector在大量添加元素的時候問題最大,list對這種情況的適應能力就非常好,deque(由多個內存塊組成)前面說過了,他是vector和list的折衷形式,內存不夠了就申請一塊新的內存,但並不拷貝老的元素。
(2)查找速度:序列容器區分容器是否已排序,排序好的就是logn,沒有的是最好是n,關聯容器的話,存儲的時候存儲的是一棵紅黑樹(一種更為嚴格的平衡二叉樹,文檔最后有介紹),總是能達到對數時間復雜度(O(logN))的效率,因為關聯容器是按照鍵值排好序的。
(3)連續內存:如果想任意位置插入元素的話,還是不考慮vector、deque
(4)元素的排序:關聯容易會按照某種等價關系排序
(5)內存是否和C兼容:vector兼容
所以優缺點是:
1. Vector的數據模型就是數組。
優點:內存和C完全兼容、高效隨機訪問、節省空間
缺點:內部插入刪除元素代價巨大、動態大小查過自身容量需要申請大量內存做大量拷貝。
2. List的數據結構模型是鏈表
優點:任意位置插入刪除元素常量時間復雜度、兩個容器融合是常量時間復雜度
缺點:不支持隨機訪問、比vector占用更多的存儲空間
3. Deque的數據模型是數組和鏈表的折衷:
優點:高效隨機訪問、內部插入刪除元素效率方便、兩端push pop
缺點:內存占用比較高
4. Map、set、multimap、multiset的數據結構模型是二叉樹(紅黑樹)
優點:元素會按照鍵值排序、查找是對數時間復雜度、通過鍵值查元素、map提供了下標訪問