一、空間分配器算法
std::alloc用於容器中內存空間的分配和釋放,以及分配內存的管理。construct()、destroy()等全局函數用於爲對象的構造和析構。
數組
二、迭代器和trains數據結構
迭代器將容器和算法聯繫起來,行爲相似指針。各個容器都本身實現本身的迭代器,最重要的是對operator*和operator-> 進行重載。每一個迭代器裏都定義了一些類型,包括所指對象的類型。trains將這些類型提取出來。函數
STL的容器能夠分爲如下幾個大類:
一:序列容器, 有vector, list, deque.性能
二 : 關聯容器, 有set, multiset, map, mulmapspa
hash_set,hash_map, hash_multiset, hash_multimap指針
序列容器是表示容器可序的,注意不是已經排好序的。好比vector,能夠經過push_back記錄下進入數組的順序。對象
(1) vector
內部數據結構:數組。
隨機訪問每一個元素,所須要的時間爲常量。
vector的迭代器在內存從新分配時將失效(它所指向的元素在該操做的先後再也不相同)。當把超過capacity()-size()個元素插入 vector中時,內存會從新分配,全部的迭代器都將失效;不然,指向當前元素之後的任何元素的迭代器都將失效。當刪除元素時,指向被刪除元素之後的任何 元素的迭代器都將失效。排序
在添加新元素時,若是剩餘空間足夠,就之間添加;若是剩餘空間不夠,須要開闢一塊新的內存(爲原內存2倍),而後複製舊的內存到新內存,添加元素,釋放就內存。索引
(2)deque(雙端隊列)
內部數據結構:一段段數組(空間)。還分配了一段連續空間用來管理這些數組。
隨機訪問每一個元素,所須要的時間爲常量。
增長任何元素都將使deque的迭代器失效。在deque的中間刪除元素將使迭代器失效。在deque的頭或尾刪除元素時,只有指向該元素的迭代器失效。
stack(堆)和queue(隊列)默認底層的數據結構都是deque,stack是隻有一端進出;queue是一端進,一端出。默認是deque,用list也能實現
(3)list
內部數據結構:雙向鏈表。
不能隨機訪問一個元素。
增長任何元素都不會使迭代器失效。刪除元素時,除了指向當前被刪除元素的迭代器外,其它迭代器都不會失效。
總結:
一、若是你須要高效的隨即存取,而不在意插入和刪除的效率,使用vector
二、若是你須要大量的插入和刪除,而不關心隨即存取,則應使用list
三、若是你須要隨即存取,並且關心兩端數據的插入和刪除,則應使用deque
(3)set map
基於紅黑樹(RB-tree),查找(插入、刪除)的時間複雜度是對數的O(logN)。自定義的鍵值類型須要重載<運算符,由於set、map是有排序的。
若是迭代器所指向的元素被刪除,則該迭代器失效。其它任何增長、刪除元素的操做都不會使迭代器失效。
(3)hash_set hash_map
底層使用hash_table,vector做爲數組,用開鏈法解決散列衝突。鍵值類型要實現hash函數,有的內置類型在hash_table中有默認的hash函數,可是自定義類型沒有。因此合適的數組大小,hash函數對性能的影響很大。
與set、map相比:
1.查找(插入、刪除)可能更快:在「不碰撞的狀況下」,其實換句話說,就是要有足夠好的hash函數,它要能使key到value的映射足夠均勻,認爲它是O(1)級的;不然,在最壞的狀況下,它的計算量就退化到O(N)級,變成和鏈表同樣。
2.須要更多內存:經過Hash表來加快查找過程,將待存數據的key通過映射函數變成一個數組(通常是vector)的索引,STL是用開鏈的方法來解決的,每個數組的元素維護一個list,他把相同索引值的數據存入一個list;可是須要更多的內存來存放這些Hash桶元素,所以能夠算得上是採用空間來換取時間策略。