大多過載的演算法都同時有兩個版本的:
- 用"=="判斷元素相等,或者用"x<y,y<x"比較大小判斷相等
- 多出一個型別引數"Pred"和函式形參"Pred op",通過判斷表示式op(x,y)的返回值來判斷x==y或者x<y。 比如有兩個版本的min_element:
iterator min_element(iterator first, iterator last);
iterator min_element(iterator first, iterator last,Pred op);
複製程式碼
STL中的演算法大致有以下7種:
需要說明的是,演算法名字並不代表實際意義,可以用自己的想象力做演算法名字之外的事情;同時有些非常用演算法並未列出
1.不變序列演算法
該類演算法不修改演算法所作用的容器或物件
適用於順序容器和關聯容器
時間複雜度都是O(n)
常用演算法:
名稱 | 說明(程式碼為函式模板,InIt代表迭代器,簡單的不說明) |
---|---|
find | InIt find(InIt first, InIt last, const T& val); |
count | size_t count(InIt first, InIt last, const T& val); |
min | |
max | |
min_element | FwdIt min_element(FwdIt first, FwdIt last); |
max_element | FwdIt max_element(FwdIt first, FwdIt last); |
search | 查詢另一區間第一次出現的位置 |
find_first_of | |
find_end | |
equal | 判斷兩區間是否相等 |
for_each | Fun for_each(InIt first, InIt last, Fun f); |
2.變值演算法
會修改源區間或目標區間元素的值
值被修改的那個區間不可以是關聯容器(關聯容器會涉及到重新排序)
常用演算法:
名稱 | 說明(Init輸入迭代器,OutIt輸出迭代器) |
---|---|
for_each | |
copy | OutIt copy(InIt first, InIt last, OutIt x); |
copy_backward | |
transform | OutIt transform(InIt first, InIt last, OutIt x, Unop uop); |
swap_ranges | |
fill | |
fill_n | |
generate | |
generate_n | |
replace | |
replace_if | |
replace_copy | |
replace_copy_if |
3.刪除演算法
刪除一個容器中的某些元素
刪除演算法不應作用於關聯容器(關聯容器會涉及到元素排序)
演算法複雜度都是o(n)
刪除並不會使元素減少
* 將所有應該被刪除的元素看做空位子
* 用留下的元素從後往前移, 依次去填空位子
* 空位置填滿後,剩下的位置由剛開始的所在位置元素填(即剩下的位置不變)
複製程式碼
名稱 | 說明 |
---|---|
remove | 刪除區間中等於某個值的元素 |
unique | 刪除區間中連續相等的元素, 只留下一個(可自定義比較器) |
remove_if | |
remove_copy | |
remove_copy_if | |
unique_copy |
4.變序演算法
變序演算法改變容器中元素的順序,但是不改變元素的值
變序演算法不適用於關聯容器
演算法複雜度都是O(n)的
名稱 | 說明(FwdIt迭代器) |
---|---|
reverse | 顛倒區間的前後次序 |
rotate | 將區間進行迴圈左移 |
next_permutation | 將區間改為下一個排列(可自定義比較器) |
prev_permutation | 將區間改為上一個排列(可自定義比較器) |
random_shuffle | 隨機打亂區間內元素的順序 |
stable_patition | 把區間內滿足某個條件的元素移到前面,不滿足該條件的移到後面,而對這兩部分元素, 分別保持它們原來的先後次序不變 |
partition | 把區間內滿足某個條件的元素移到前面,不滿足該條件的移到後面 |
rotate_copy | 將區間以首尾相接的形式進行旋轉後的結果拷貝到另一個區間,源區間不變 |
reverse_copy | 把一個區間顛倒後的結果拷貝到另一個區間,源區間不變 |
5.排序演算法
排序演算法需要隨機訪問迭代器的支援
不適用於關聯容器和list
比前面的變序演算法複雜度更高, 一般是O(nlog(n))
名稱 | 說明(RanIt迭代器) |
---|---|
sort | void sort(RanIt first, RanIt last, Pred pr) |
stable_sort | |
partial_sort | |
partial_sort_copy | |
nth_element | |
make_heap | |
push_heap | |
pop_heap | |
sort_heap |
sort 實際上是快速排序, 時間複雜度 O(n*log(n))
- 平均效能最優
- 但是最壞的情況下, 效能可能非常差
如果要保證 “最壞情況下” 的效能, 那麼可以使用stable_sort
- stable_sort 實際上是歸併排序, 特點是能保持相等元素之間的先後次序
- 在有足夠儲存空間的情況下, 複雜度為 n * log(n), 否則複雜度為n * log(n) * log(n)
- stable_sort 用法和 sort相同。
排序演算法要求隨機存取迭代器的支援, 所以list不能使用排序演算法, 要使用list自帶的sort成員函式list::sort。
6.有序區間演算法
要求所操作的區間是已經從小到大排好序的
需要隨機訪問迭代器的支援
有序區間演算法不能用於關聯容器和list
名稱 | 說明(前6個很常用) |
---|---|
binary_search | 判斷區間中是否包含某個元素(折半查詢) |
includes | 判斷是否一個區間中的每個元素,都在另一個區間中 |
lower_bound | 查詢最後一個不小於某值的元素的位置 |
upper_bound | 查詢第一個大於某值的元素的位置 |
equal_range | 同時獲取lower_bound和upper_bound |
merge | 合併兩個有序區間到第三個區間 |
set_union | 將兩個有序區間的並拷貝到第三個區間 |
set_intersection | 將兩個有序區間的交拷貝到第三個區間 |
set_difference | 將兩個有序區間的差拷貝到第三個區間 |
set_symmetric_difference | 將兩個有序區間的對稱差拷貝到第三個區間 |
inplace_merge | 將兩個連續的有序區間原地合併為一個有序區間 |
bitset
bitset一個實際上不屬於STL演算法,但是會很常用。
template<size_t N>
class bitset{
...
}
bitset<40>bst; #bst是一個由40位組成的物件,用bitset的函式可以方便地訪問任何一位
複製程式碼
bitset的成員函式:
bitset<N>& operator&=(const bitset<N>& rhs);
bitset<N>& operator|=(const bitset<N>& rhs);
bitset<N>& operator^=(const bitset<N>& rhs);
bitset<N>& operator<<=(size_t num);
bitset<N>& operator>>=(size_t num);
bitset<N>& set(); //全部設成1
bitset<N>& set(size_t pos, bool val = true); //設定某位
bitset<N>& reset(); //全部設成0
bitset<N>& reset(size_t pos); //某位設成0
bitset<N>& flip(); //全部翻轉
bitset<N>& flip(size_t pos); //翻轉某位
reference operator[](size_t pos); //返回對某位的引用
bool operator[](size_t pos) const; //判斷某位是否為1
reference at(size_t pos);
bool at(size_t pos) const;
unsigned long to_ulong() const; //轉換成整數
string to_string() const; //轉換成字串
size_t count() const; //計算1的個數
size_t size() const;
bool operator==(const bitset<N>& rhs) const;
bool operator!=(const bitset<N>& rhs) const;
bool test(size_t pos) const; //測試某位是否為 1
bool any() const; //是否有某位為1
bool none() const; //是否全部為0
bitset<N> operator<<(size_t pos) const;
bitset<N> operator>>(size_t pos) const;
bitset<N> operator~();
static const size_t bitset_size = N;
#注意: 第0位在最右邊
複製程式碼
總結起來呢,就是實現容器或物件元素的查刪改比較排序。