STL標準模板庫 知識點總結

一、STL概述

爲了創建數據結構和算法的一套標準,而且下降他們之間的耦合關係,以提高各自的獨立性、彈性、交互操做性(相互合做性,interoperability),誕生了STL。html

STL提供了六大組件,彼此之間能夠組合套用,這六大組件分別是:容器、算法、迭代器、仿函數、適配器(配接器)、空間配置器前端

  • 容器:各類數據結構,如vector、list、deque、set、map等,用來存放數據,從實現角度來看,STL容器是一種class template。node

  • 算法:各類經常使用的算法,如sort、find、copy、for_each。從實現的角度來看,STL算法是一種function tempalte.ios

  • 迭代器:扮演了容器與算法之間的膠合劑,共有五種類型,從實現角度來看,迭代器是一種將operator* , operator-> , operator++,operator–等指針相關操做予以重載的class template. 全部STL容器都附帶有本身專屬的迭代器,只有容器的設計者才知道如何遍歷本身的元素。原生指針(native pointer)也是一種迭代器。程序員

  • 仿函數:行爲相似函數,可做爲算法的某種策略。從實現角度來看,仿函數是一種重載了operator()的class 或者class template算法

  • 適配器:一種用來修飾容器或者仿函數或迭代器接口的東西。數組

  • 空間配置器:負責空間的配置與管理。從實現角度看,配置器是一個實現了動態空間配置、空間管理、空間釋放的class tempalte.數據結構

STL六大組件的交互關係,容器經過空間配置器取得數據存儲空間,算法經過迭代器存儲容器中的內容,仿函數能夠協助算法完成不一樣的策略的變化,適配器能夠修飾仿函數。app

二、STL的優勢

  1. STL 是 C++的一部分,所以不用額外安裝什麼,它被內建在你的編譯器以內。
  2. STL 的一個重要特性是將數據和操做分離。數據由容器類別加以管理,操做則由可定製的算法定義。迭代器在二者之間充當「粘合劑」,以使算法能夠和容器交互運做
  3. 程序員能夠不用思考 STL 具體的實現過程,只要可以熟練使用 STL 就 OK 了。這樣他們就能夠把精力放在程序開發的別的方面。
  4. STL 具備高可重用性,高性能,高移植性,跨平臺的優勢。
  5. 高可重用性:STL 中幾乎全部的代碼都採用了模板類和模版函數的方式實現,這相比於傳統的由函數和類組成的庫來講提供了更好的代碼重用機會。
  6. 高性能:如 map 能夠高效地從十萬條記錄裏面查找出指定的記錄,由於 map 是採用紅黑樹的變體實現的。
  7. 高移植性:如在項目 A 上用 STL 編寫的模塊,能夠直接移植到項目 B 上。容器和算法之間經過迭代器進行無縫鏈接。STL 幾乎全部的代碼都採用了模板類或者模板函數,這相比傳統的由函數和類組成的庫來講提供了更好的代碼重用機會。

三、容器

STL容器就是將運用最普遍的一些數據結構實現出來。less

經常使用的數據結構:數組(array) , 鏈表(list), tree(樹),棧(stack), 隊列(queue), 集合(set),映射表(map), 根據數據在容器中的排列特性,這些數據分爲序列式容器和關聯式容器兩種。

序列式容器強調值的排序,序列式容器中的每一個元素均有固定的位置,除非用刪除或插入的操做改變這個位置。Vector容器、Deque容器、List容器等。

關聯式容器是非線性的樹結構,更準確的說是二叉樹結構。各元素之間沒有嚴格的物理上的順序關係,也就是說元素在容器中並無保存元素置入容器時的邏輯順序。關聯式容器另外一個顯著特色是:在值中選擇一個值做爲關鍵字key,這個關鍵字對值起到索引的做用,方便查找。Set/multiset容器 Map/multimap容器

容器 底層數據結構 時間複雜度 有無序 可不可重複
array 數組 隨機讀改 O(1) 無序 可重複
vector 數組 隨機讀改、尾部插入、尾部刪除 O(1)頭部插入、頭部刪除 O(n) 無序 可重複
deque 雙端隊列 頭尾插入、頭尾刪除 O(1) 無序 可重複
forward_list 單向鏈表 插入、刪除 O(1) 無序 可重複
list 雙向鏈表 插入、刪除 O(1) 無序 可重複
stack deque / list 頂部插入、頂部刪除 O(1) 無序 可重複
queue deque / list 尾部插入、頭部刪除 O(1) 無序 可重複
priority_queue vector /max-heap 插入、刪除 O(log2n) 有序 可重複
set 紅黑樹 插入、刪除、查找 O(log2n) 有序 不可重複
multiset 紅黑樹 插入、刪除、查找 O(log2n) 有序 可重複
map 紅黑樹 插入、刪除、查找 O(log2n) 有序 不可重複
multimap 紅黑樹 插入、刪除、查找 O(log2n) 有序 可重複
unordered_set 哈希表 插入、刪除、查找 O(1) 最差 O(n) 無序 不可重複
unordered_multiset 哈希表 插入、刪除、查找 O(1) 最差 O(n) 無序 可重複
unordered_map 哈希表 插入、刪除、查找 O(1) 最差 O(n) 無序 不可重複
unordered_multimap 哈希表 插入、刪除、查找 O(1) 最差 O(n) 無序 可重複

1. array

array 是固定大小的順序容器,它們保存了一個以嚴格的線性順序排列的特定數量的元素。

方法 說明
begin 返回指向數組容器中第一個元素的迭代器
end 返回指向數組容器中最後一個元素以後的理論元素的迭代器
rbegin 返回指向數組容器中最後一個元素的反向迭代器
rend 返回一個反向迭代器,指向數組中第一個元素以前的理論元素
cbegin 返回指向數組容器中第一個元素的常量迭代器(const_iterator)
cend 返回指向數組容器中最後一個元素以後的理論元素的常量迭代器(const_iterator)
crbegin 返回指向數組容器中最後一個元素的常量反向迭代器(const_reverse_iterator)
crend 返回指向數組中第一個元素以前的理論元素的常量反向迭代器(const_reverse_iterator)
size 返回數組容器中元素的數量
max_size 返回數組容器可容納的最大元素數
empty 返回一個布爾值,指示數組容器是否爲空
operator[] 返回容器中第 n(參數)個位置的元素的引用
at 返回容器中第 n(參數)個位置的元素的引用
front 返回對容器中第一個元素的引用
back 返回對容器中最後一個元素的引用
data 返回指向容器中第一個元素的指針
fill 用 val(參數)填充數組全部元素
swap 經過 x(參數)的內容交換數組的內容
get(array) 形如 std::get<0>(myarray);傳入一個數組容器,返回指定位置元素的引用
relational operators (array) 形如 arrayA > arrayB;依此比較數組每一個元素的大小關係

2. vector

vector 是表示能夠改變大小的數組的序列容器。

具體函數可參考:http://www.javashuo.com/article/p-ktysaiue-mq.html

3. deque

deque容器爲一個給定類型的元素進行線性處理,像向量同樣,它可以快速地隨機訪問任一個元素,而且可以高效地插入和刪除容器的尾部元素。但它又與vector不一樣,deque支持高效插入和刪除容器的頭部元素,所以也叫作雙端隊列。

deque的中控器: deque是由一段一段的定量連續空間構成。一旦有必要在deque的前端或尾端增長新空間,便配置一段定量連續空間,串接在整個deque的頭端或尾端。deque的最大任務,即是在這些分段的定量連續空間上,維護其總體連續的假象,並提供隨機存取的接口。避開了「從新配置、複製、釋放」的輪迴,代價則是複雜的迭代器結構。

 

 

deque採用一塊所謂的map(不是STL的map容器)做爲主控。

map是一小塊連續空間,其中每一個元素(此處稱爲一個節點,node)都是指針,指向另外一段(較大的)連續線性空間,稱爲緩衝區。

緩衝區纔是deque的儲存空間主體。

 1 template<class T, class Alloc = alloc, size_t BufSiz = 0>  
 2 class deque{  
 3 public :  
 4     typedef T value_type ;  
 5     typedef value_type* pointer ;  
 6     ...  
 7 protected :  
 8     //元素的指針的指針(pointer of pointer of T)  
 9     // 其實就是T**,一個二級指針,維護一個二維數組
10     typedef pointer* map_pointer ; 
11   
12 protected :  
13     map_pointer map ; //指向map,map是塊連續空間,其內的每一個元素  
14                       //都是一個指針(稱爲節點),指向一塊緩衝區  
15     size_type map_size ;//map內可容納多少指針  
16     ...  
17 };  

map實際上是一個T**,也就是說它是一個指針,所指之物也是一個指針,指向型別爲T的一塊空間。

具體函數參考:http://www.javashuo.com/article/p-smrdjnsr-mp.html

4. list

 

list雙向鏈表,是序列容器,容許在序列中的任何地方進行常數時間插入和擦除操做,並在兩個方向上進行迭代,能夠高效地進行插入刪除元素。

list容器的底層實現:

和 array、vector 這些容器迭代器的實現方式不一樣,因爲 list 容器的元素並非連續存儲的,因此該容器迭代器中,必須包含一個能夠指向 list 容器的指針,而且該指針還能夠藉助重載的 *、++、--、==、!= 等運算符,實現迭代器正確的遞增、遞減、取值等操做。

 1 template<tyepname T,...>
 2 struct __list_iterator{
 3     __list_node<T>* node;
 4     //...
 5     //重載 == 運算符
 6     bool operator==(const __list_iterator& x){return node == x.node;}
 7     //重載 != 運算符
 8     bool operator!=(const __list_iterator& x){return node != x.node;}
 9     //重載 * 運算符,返回引用類型
10     T* operator *() const {return *(node).myval;}
11     //重載前置 ++ 運算符
12     __list_iterator<T>& operator ++(){
13         node = (*node).next;
14         return *this;
15     }
16     //重載後置 ++ 運算符
17     __list_iterator<T>& operator ++(int){
18         __list_iterator<T> tmp = *this;
19         ++(*this);
20         return tmp;
21     }
22     //重載前置 -- 運算符
23     __list_iterator<T>& operator--(){
24         node = (*node).prev;
25         return *this;
26     }
27     //重載後置 -- 運算符
28     __list_iterator<T> operator--(int){
29         __list_iterator<T> tmp = *this;
30         --(*this);
31         return tmp;
32     }
33     //...
34 }

5. forward_list

在頭文件<forward_list>中,與list相似,區別就是list時雙鏈表,forward_list是單鏈表,forward_list(單向鏈表)是序列容器,容許在序列中的任何地方進行恆定的時間插入和擦除操做。在鏈表的任何位置進行插入/刪除操做都很是快。

forward_list的特色

  • forward_list只提供正向迭代器,所以不支持反向迭代器,好比rbegin()等成員函數。
  • forward_list不提供size()成員函數。
  • forward_list沒有指向最末元素的錨點,所以不提供back()、push_back()和pop_back()。
  • forward_list不提供隨機訪問,這一點跟list相同。
  • 插入和刪除元素不會形成「指向至其餘元素」的指針,引用和迭代器失效。

6. stack

stack沒有迭代器,是一種容器適配器,用於在LIFO(後進先出)的操做,其中元素僅從容器的一端插入和提取。

 

stack底層通常用list或deque實現,封閉頭部便可,不用vector的緣由應該是容量大小有限制,擴容耗時.

底層用deque實現

 1 //deque<T> >中間有個空格是爲了兼容較老的版本
 2 template <class T, class Sequence = deque<T> >
 3 class stack {
 4     // 以㆘的 __STL_NULL_TMPL_ARGS 會開展爲 <>
 5     friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
 6     friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
 7 public:
 8     typedef typename Sequence::value_type value_type;
 9     typedef typename Sequence::size_type size_type;
10     typedef typename Sequence::reference reference;
11     typedef typename Sequence::const_reference const_reference;
12 protected:
13     Sequence c; // 底層容器
14 public:
15     // 如下徹底利用 Sequence c 的操做,完成 stack 的操做。
16     bool empty() const { return c.empty(); }
17     size_type size() const { return c.size(); }
18     reference top() { return c.back(); }
19     const_reference top() const { return c.back(); }
20     // deque 是兩頭可進出,stack 是末端進,末端出(因此後進者先出)。
21     void push(const value_type& x) { c.push_back(x); }
22     void pop() { c.pop_back(); }
23 };
24 
25 template <class T, class Sequence>
26 bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
27     return x.c == y.c;
28 }
29 
30 template <class T, class Sequence>
31 bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
32     return x.c < y.c;
33 }

底層用list實現

 1 #include<stack>  
 2   #include<list>  
 3   #include<algorithm>  
 4   #include <iostream>  
 5   using namespace std;  
 6     
 7   int main(){  
 8       stack<int, list<int>> istack;  
 9       istack.push(1);  
10       istack.push(3);  
11       istack.push(5);  
12         
13       cout << istack.size() << endl; //3  
14       cout << istack.top() << endl;//5  
15       istack.pop();  
16       cout << istack.top() << endl;//3  
17       cout << istack.size() << endl;//2  
18     
19       system("pause");  
20       return 0;  
21   }  

7. queue

queue 是一種容器適配器,用於在FIFO(先入先出)的操做,其中元素插入到容器的一端並從另外一端提取。

 

隊列不提供迭代器,不實現遍歷操做。

 1 template <class T, class Sequence = deque<T> >
 2 class queue {
 3   friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
 4   friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
 5 public:
 6   typedef typename Sequence::value_type value_type;
 7   typedef typename Sequence::size_type size_type;
 8   typedef typename Sequence::reference reference;
 9   typedef typename Sequence::const_reference const_reference;
10 protected:
11   Sequence c;
12 public:
13   bool empty() const { return c.empty(); }
14   size_type size() const { return c.size(); }
15   reference front() { return c.front(); }
16   const_reference front() const { return c.front(); }
17   reference back() { return c.back(); }
18   const_reference back() const { return c.back(); }
19   void push(const value_type& x) { c.push_back(x); }
20   void pop() { c.pop_front(); }
21 };
22 
23 template <class T, class Sequence>
24 bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
25   return x.c == y.c;
26 }
27 
28 template <class T, class Sequence>
29 bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
30   return x.c < y.c;
31 }

8. priority_queue

優先隊列,其底層是用堆來實現的。在優先隊列中,隊首元素必定是當前隊列中優先級最高的那一個。

9. set

集合,set 是按照特定順序存儲惟一元素的容器。

1 template<class _Kty,
2     class _Pr = less<_Kty>,
3     class _Alloc = allocator<_Kty> >
4 class set
  1. set 的 底層數據結構是 紅黑樹,一種高效的平衡檢索二叉樹。
  2. set 容器中 每個元素就是二叉樹的每個節點,對於set容器的插入刪除操做,效率都比較高,緣由是由於二叉樹的刪除插入元素並不須要進行內存拷貝和內存移動,只是改變了指針的指向。
  3. 對 set 進行插入刪除操做 都不會引發iterator的失效,由於迭代器至關於一個指針指向每個二叉樹的節點,對set的插入刪除並不會改變原有內存中節點的改變, 可是vector的插入刪除操做通常會發生內存移動和內存拷貝,因此會發生迭代器的失效。
  4. set容器的檢索速度很快,由於採用二分查找的方法 。

10. multiset

multiset容許元素重複而set不容許

1 template<class _Kty,
2     class _Pr = less<_Kty>,
3     class _Alloc = allocator<_Kty> >
4 class multiset

11. map

map 是關聯容器,按照特定順序存儲由 key value (鍵值) 和 mapped value (映射值) 組合造成的元素。

因爲 RB-tree 是一種平衡二叉搜索樹,自動排序的效果很不錯,因此標準的STL map 即以 RB-tree 爲底層機制。又因爲 map 所開放的各類操做接口,RB-tree 也都提供了,因此幾乎全部的 map 操做行爲,都只是轉調 RB-tree 的操做行爲。

方法 說明
map 構造函數
begin 返回引用容器中第一個元素的迭代器
key_comp 返回容器用於比較鍵的比較對象的副本
value_comp 返回可用於比較兩個元素的比較對象,以獲取第一個元素的鍵是否在第二個元素以前
find 在容器中搜索具備等於 k的鍵的元素,若是找到返回一個迭代器,不然返回 map::end
count 在容器中搜索具備等於 k(參數)的鍵的元素,並返回匹配的數量
lower_bound 返回一個非遞減序列 [first, last)中的第一個大於等於值 val的位置的迭代器
upper_bound 返回一個非遞減序列 [first, last)中第一個大於 val的位置的迭代器
equal_range 獲取相同元素的範圍,返回包含容器中全部具備與 k等價的鍵的元素的範圍邊界

 12. multimap

multimap 的特性以及用法與 map 徹底相同,惟一的差異在於它容許鍵值重複,所以它的插入操做採用的是底層機制 RB-tree 的 insert_equal() 而非 insert_unique。

13. unordered_set

unordered_set是基於哈希表,所以要了解unordered_set,就必須瞭解哈希表的機制。哈希表是根據關鍵碼值而進行直接訪問的數據結構,經過相應的哈希函數(也稱散列函數)處理關鍵字獲得相應的關鍵碼值,關鍵碼值對應着一個特定位置,用該位置來存取相應的信息,這樣就能以較快的速度獲取關鍵字的信息。

四、算法

1. 簡單查找算法,要求輸入迭代器(input iterator)

1 find(beg, end, val); // 返回一個迭代器,指向輸入序列中第一個等於 val 的元素,未找到返回 end
2 find_if(beg, end, unaryPred); // 返回一個迭代器,指向第一個知足 unaryPred 的元素,未找到返回 end
3 find_if_not(beg, end, unaryPred); // 返回一個迭代器,指向第一個令 unaryPred 爲 false 的元素,未找到返回 end
4 count(beg, end, val); // 返回一個計數器,指出 val 出現了多少次
5 count_if(beg, end, unaryPred); // 統計有多少個元素知足 unaryPred
6 all_of(beg, end, unaryPred); // 返回一個 bool 值,判斷是否全部元素都知足 unaryPred
7 any_of(beg, end, unaryPred); // 返回一個 bool 值,判斷是否任意(存在)一個元素知足 unaryPred
8 none_of(beg, end, unaryPred); // 返回一個 bool 值,判斷是否全部元素都不知足 unaryPred

2. 查找重複值的算法,傳入向前迭代器(forward iterator)

1 adjacent_find(beg, end); // 返回指向第一對相鄰重複元素的迭代器,無相鄰元素則返回 end
2 adjacent_find(beg, end, binaryPred); // 返回指向第一對相鄰重複元素的迭代器,無相鄰元素則返回 end
3 search_n(beg, end, count, val); // 返回一個迭代器,今後位置開始有 count 個相等元素,不存在則返回 end
4 search_n(beg, end, count, val, binaryPred); // 返回一個迭代器,今後位置開始有 count 個相等元素,不存在則返回 end

3. 查找子序列算法,除 find_first_of(前兩個輸入迭代器,後兩個前向迭代器) 外,都要求兩個前向迭代器

1 search(beg1, end1, beg2, end2); // 返回第二個輸入範圍(子序列)在爹一個輸入範圍中第一次出現的位置,未找到則返回 end1
2 search(beg1, end1, beg2, end2, binaryPred); // 返回第二個輸入範圍(子序列)在爹一個輸入範圍中第一次出現的位置,未找到則返回 end1
3 find_first_of(beg1, end1, beg2, end2); // 返回一個迭代器,指向第二個輸入範圍中任意元素在第一個範圍中首次出現的位置,未找到則返回end1
4 find_first_of(beg1, end1, beg2, end2, binaryPred); // 返回一個迭代器,指向第二個輸入範圍中任意元素在第一個範圍中首次出現的位置,未找到則返回end1
5 find_end(beg1, end1, beg2, end2); // 相似 search,但返回的最後一次出現的位置。若是第二個輸入範圍爲空,或者在第一個輸入範圍爲空,或者在第一個輸入範圍中未找到它,則返回 end1
6 find_end(beg1, end1, beg2, end2, binaryPred); // 相似 search,但返回的最後一次出現的位置。若是第二個輸入範圍爲空,或者在第一個輸入範圍爲空,或者在第一個輸入範圍中未找到它,則返回 end1

4. 其餘只讀算法,傳入輸入迭代器

1 for_each(beg, end, unaryOp); // 對輸入序列中的每一個元素應用可調用對象 unaryOp,unaryOp 的返回值被忽略
2 mismatch(beg1, end1, beg2); // 比較兩個序列中的元素。返回一個迭代器的 pair,表示兩個序列中第一個不匹配的元素
3 mismatch(beg1, end1, beg2, binaryPred); // 比較兩個序列中的元素。返回一個迭代器的 pair,表示兩個序列中第一個不匹配的元素
4 equal(beg1, end1, beg2); // 比較每一個元素,肯定兩個序列是否相等。
5 equal(beg1, end1, beg2, binaryPred); // 比較每一個元素,肯定兩個序列是否相等。

5. 二分搜索算法,傳入前向迭代器或隨機訪問迭代器(random-access iterator),要求序列中的元素已是有序的

1 lower_bound(beg, end, val); // 返回一個非遞減序列 [beg, end) 中的第一個大於等於值 val 的位置的迭代器,不存在則返回 end
2 lower_bound(beg, end, val, greater<type>()); // 返回一個非遞減序列 [beg, end) 中的第一個小於等於值 val 的位置的迭代器,不存在則返回 end
3 upper_bound(beg, end, val); // 返回一個非遞減序列 [beg, end) 中第一個大於 val 的位置的迭代器,不存在則返回 end
4 upper_bound(beg, end, val, greater<type>()); // 返回一個非遞減序列 [beg, end) 中第一個小於等於 val 的位置的迭代器,不存在則返回 end
5 equal_range(beg, end, val); // 返回一個 pair,其 first 成員是 lower_bound 返回的迭代器,其 second 成員是 upper_bound 返回的迭代器
6 binary_search(beg, end, val); // 返回一個 bool 值,指出序列中是否包含等於 val 的元素。對於兩個值 x 和 y,當 x 不小於 y 且 y 也不小於 x 時,認爲它們相等。

6. 只寫不讀算法,要求輸出迭代器(output iterator)

1 fill(beg, end, val); // 將 val 賦予每一個元素,返回 void
2 fill_n(beg, cnt, val); // 將 val 賦予 cnt 個元素,返回指向寫入到輸出序列最有一個元素以後位置的迭代器
3 genetate(beg, end, Gen); // 每次調用 Gen() 生成不一樣的值賦予每一個序列,返回 void
4 genetate_n(beg, cnt, Gen); // 每次調用 Gen() 生成不一樣的值賦予 cnt 個序列,返回指向寫入到輸出序列最有一個元素以後位置的迭代器

7. 使用輸入迭代器的寫算法,讀取一個輸入序列,將值寫入到一個輸出序列(dest)中

 1 copy(beg, end, dest); // 從輸入範圍將元素拷貝全部元素到 dest 指定定的目的序列
 2 copy_if(beg, end, dest, unaryPred); // 從輸入範圍將元素拷貝知足 unaryPred 的元素到 dest 指定定的目的序列
 3 copy_n(beg, n, dest); // 從輸入範圍將元素拷貝前 n 個元素到 dest 指定定的目的序列
 4 move(beg, end, dest); // 對輸入序列中的每一個元素調用 std::move,將其移動到迭代器 dest 開始始的序列中
 5 transform(beg, end, dest, unaryOp); // 調用給定操做(一元操做),並將結果寫到dest中
 6 transform(beg, end, beg2, dest, binaryOp); // 調用給定操做(二元操做),並將結果寫到dest中
 7 replace_copy(beg, end, dest, old_val, new_val); // 將每一個元素拷貝到 dest,將等於 old_val 的的元素替換爲 new_val
 8 replace_copy_if(beg, end, dest, unaryPred, new_val); // 將每一個元素拷貝到 dest,將知足 unaryPred 的的元素替換爲 new_val
 9 merge(beg1, end1, beg2, end2, dest); // 兩個輸入序列必須都是有序的,用小於號運算符將合併後的序列寫入到 dest 中
10 merge(beg1, end1, beg2, end2, dest, comp); // 兩個輸入序列必須都是有序的,使用給定的比較操做(comp)將合併後的序列寫入到 dest 中

8. 劃分算法,要求雙向選代器(bidirectional iterator)

1 is_partitioned(beg, end, unaryPred); // 若是全部知足謂詞 unaryPred 的元素都在不知足 unarypred 的元素以前,則返回 true。若序列爲空,也返回 true
2 partition_copy(beg, end, dest1, dest2, unaryPred); // 將知足 unaryPred 的元素拷貝到到 dest1,並將不知足 unaryPred 的元素拷貝到到 dest2。返回一個迭代器 pair,其 first 成員表示拷貝到 dest1 的的元素的末尾,second 表示拷貝到 dest2 的元素的末尾。
3 partitioned_point(beg, end, unaryPred); // 輸入序列必須是已經用 unaryPred 劃分過的。返回知足  unaryPred 的範圍的尾後迭代器。若是返回的迭代器不是 end,則它指向的元素及其後的元素必須都不知足 unaryPred
4 stable_partition(beg, end, unaryPred); // 使用 unaryPred 劃分輸入序列。知足 unaryPred 的元素放置在序列開始,不知足的元素放在序列尾部。返回一個迭代器,指向最後一個知足 unaryPred 的元素以後的位置若是全部元素都不知足 unaryPred,則返回 beg
5 partition(beg, end, unaryPred); // 使用 unaryPred 劃分輸入序列。知足 unaryPred 的元素放置在序列開始,不知足的元素放在序列尾部。返回一個迭代器,指向最後一個知足 unaryPred 的元素以後的位置若是全部元素都不知足 unaryPred,則返回 beg

9. 排序算法,要求隨機訪問迭代器(random-access iterator)

 1 sort(beg, end); // 排序整個範圍
 2 stable_sort(beg, end); // 排序整個範圍(穩定排序)
 3 sort(beg, end, comp); // 排序整個範圍
 4 stable_sort(beg, end, comp); // 排序整個範圍(穩定排序)
 5 is_sorted(beg, end); // 返回一個 bool 值,指出整個輸入序列是否有序
 6 is_sorted(beg, end, comp); // 返回一個 bool 值,指出整個輸入序列是否有序
 7 is_sorted_until(beg, end); // 在輸入序列中査找最長初始有序子序列,並返回子序列的尾後迭代器
 8 is_sorted_until(beg, end, comp); // 在輸入序列中査找最長初始有序子序列,並返回子序列的尾後迭代器
 9 partial_sort(beg, mid, end); // 排序 mid-beg 個元素。即,若是 mid-beg 等於 42,則此函數將值最小的 42 個元素有序放在序列前 42 個位置
10 partial_sort(beg, mid, end, comp); // 排序 mid-beg 個元素。即,若是 mid-beg 等於 42,則此函數將值最小的 42 個元素有序放在序列前 42 個位置
11 partial_sort_copy(beg, end, destBeg, destEnd); // 排序輸入範圍中的元素,並將足夠多的已排序元素放到 destBeg 和 destEnd 所指示的序列中
12 partial_sort_copy(beg, end, destBeg, destEnd, comp); // 排序輸入範圍中的元素,並將足夠多的已排序元素放到 destBeg 和 destEnd 所指示的序列中
13 nth_element(beg, nth, end); // nth 是一個迭代器,指向輸入序列中第 n 大的元素。nth 以前的元素都小於等於它,而以後的元素都大於等於它
14 nth_element(beg, nth, end, comp); // nth 是一個迭代器,指向輸入序列中第 n 大的元素。nth 以前的元素都小於等於它,而以後的元素都大於等於它

10. 使用前向迭代器的重排算法。普通版本在輸入序列自身內部重拍元素,_copy 版本完成重拍後寫入到指定目的序列中,而不改變輸入序列

 1 remove(beg, end, val); // 經過用保留的元素覆蓋要刪除的元素實現刪除 ==val 的元素,返回一個指向最後一個刪除元素的尾後位置的迭代器
 2 remove_if(beg, end, unaryPred); // 經過用保留的元素覆蓋要刪除的元素實現刪除知足 unaryPred 的元素,返回一個指向最後一個刪除元素的尾後位置的迭代器
 3 remove_copy(beg, end, dest, val); // 經過用保留的元素覆蓋要刪除的元素實現刪除 ==val 的元素,返回一個指向最後一個刪除元素的尾後位置的迭代器
 4 remove_copy_if(beg, end, dest, unaryPred); // 經過用保留的元素覆蓋要刪除的元素實現刪除知足 unaryPred 的元素,返回一個指向最後一個刪除元素的尾後位置的迭代器
 5 unique(beg, end); // 經過對覆蓋相鄰的重複元素(用 == 肯定是否相同)實現重排序列。返回一個迭代器,指向不重複元素的尾後位置
 6 unique (beg, end, binaryPred); // 經過對覆蓋相鄰的重複元素(用 binaryPred 肯定是否相同)實現重排序列。返回一個迭代器,指向不重複元素的尾後位置
 7 unique_copy(beg, end, dest); // 經過對覆蓋相鄰的重複元素(用 == 肯定是否相同)實現重排序列。返回一個迭代器,指向不重複元素的尾後位置
 8 unique_copy_if(beg, end, dest, binaryPred); // 經過對覆蓋相鄰的重複元素(用 binaryPred 肯定是否相同)實現重排序列。返回一個迭代器,指向不重複元素的尾後位置
 9 rotate(beg, mid, end); // 圍繞 mid 指向的元素進行元素轉動。元素 mid 成爲爲首元素,隨後是 mid+1 到到 end 以前的元素,再接着是 beg 到 mid 以前的元素。返回一個迭代器,指向原來在 beg 位置的元素
10 rotate_copy(beg, mid, end, dest); // 圍繞 mid 指向的元素進行元素轉動。元素 mid 成爲爲首元素,隨後是 mid+1 到到 end 以前的元素,再接着是 beg 到 mid 以前的元素。返回一個迭代器,指向原來在 beg 位置的元素

11. 使用雙向迭代器的重排算法

1 reverse(beg, end); // 翻轉序列中的元素,返回 void
2 reverse_copy(beg, end, dest);; // 翻轉序列中的元素,返回一個迭代器,指向拷貝到目的序列的元素的尾後位置

12. 使用隨機訪問迭代器的重排算法

1 random_shuffle(beg, end); // 混洗輸入序列中的元素,返回 void
2 random_shuffle(beg, end, rand); // 混洗輸入序列中的元素,rand 接受一個正整數的隨機對象,返回 void
3 shuffle(beg, end, Uniform_rand); // 混洗輸入序列中的元素,Uniform_rand 必須知足均勻分佈隨機數生成器的要求,返回 void

13. 最大值和最小值

 1 min(val1, va12); // 返回 val1 和 val2 中的最小值,兩個實參的類型必須徹底一致。參數和返回類型都是 const的引引用,意味着對象不會被拷貝。下略
 2 min(val1, val2, comp);
 3 min(init_list);
 4 min(init_list, comp);
 5 max(val1, val2);
 6 max(val1, val2, comp);
 7 max(init_list);
 8 max(init_list, comp);
 9 minmax(val1, val2); // 返回一個 pair,其 first 成員爲提供的值中的較小者,second 成員爲較大者。下略
10 minmax(vall, val2, comp);
11 minmax(init_list);
12 minmax(init_list, comp);
13 min_element(beg, end); // 返回指向輸入序列中最小元素的迭代器
14 min_element(beg, end, comp); // 返回指向輸入序列中最小元素的迭代器
15 max_element(beg, end); // 返回指向輸入序列中最大元素的迭代器
16 max_element(beg, end, comp); // 返回指向輸入序列中最大元素的迭代器
17 minmax_element(beg, end); // 返回一個 pair,其中 first 成員爲最小元素,second 成員爲最大元素
18 minmax_element(beg, end, comp); // 返回一個 pair,其中 first 成員爲最小元素,second 成員爲最大元素

14. 字典序比較,根據第一對不相等的元素的相對大小來返回結果。若是第一個序列在字典序中小於第二個序列,則返回 true。不然,返回 fa1se。若是個序列比另外一個短,且全部元素都與較長序列的對應元素相等,則較短序列在字典序中更小。若是序列長度相等,且對應元素都相等,則在字典序中任何一個都不大於另一個。

1 lexicographical_compare(beg1, end1, beg2, end2);
2 lexicographical_compare(beg1, end1, beg2, end2, comp);

5. 如何選擇合適的容器

須要根據容器的特色和使用場景而定,可能知足需求的不止一種容器。

按是否有序關聯性分爲:

  1. 序列式容器:array、vector、deque、list 和 forward_list;
  2. 關聯式容器:map、multimap、set 和 multiset;
  3. 無序關聯式容器:unordered_map、unordered_multimap、unordered_set 和 unordered_multiset;
  4. 容器適配器:stack、queue 和 priority_queue。 根據容器底層採用是不是連續的存儲空間分爲:
  5. 採用連續的存儲空間:array、vector、deque;
  6. 採用分散的存儲空間:list、forward_list 以及全部的關聯式容器和哈希容器。

注意:deque 容器歸爲使用連續存儲空間的這一類,是存在爭議的。由於 deque 容器底層採用一段一段的連續空間存儲元素,可是各段存儲空間之間並不必定是緊挨着的。

選擇容器的幾點建議:

  • 若是隻是存儲肯定或不肯定的對象,而不去刪除它們,能夠選用vector。就是由於vector是數組的替代品,是連續內存的,不適合頻繁的刪除。
  • 若是在容器的指定位置插入新元素,則只能選擇序列式容器,不選擇關聯式容器和哈希容器。
  • 若是頻繁的插入和刪除,能夠選用list(鏈表),內存不是連續的,能夠方便的插入和刪除,可是不支持索引訪問。
  • 數據量很大,不在意他們的排序,要求效率,對容器中各元素的存儲位置沒有要求,能夠考慮使用哈希容器,反之就要避免使用哈希容器。
  • 若是是隨機訪問迭代器,選擇 array、vector、deque。
  • 若是是雙向迭代器,考慮 list 序列式容器以及全部的關聯式容器。
  • 若是必須是前向迭代器,考慮 forward_list序列式容器以及全部的哈希容器。
  • 若是插入或刪除操做時,容器中的其它元素不移動?選擇不是array、vector、deque的其它容器。

 

原文連接:https://mp.weixin.qq.com/s/W7ix5j9YkevTpIugrdS6Rw

相關文章
相關標籤/搜索