STL中的算法小結

(1)要運用STL的算法,首先必須包含頭文件<algorithm>,某些STL算法用於數值處理,所以被定義於頭文件<numeric>

(2)全部STL算法都被設計用來處理一個或多個迭代器區間,第一個區間一般以起點和終點表示,至於其餘區間,多數狀況下你只需提供起點便足以,其終點能夠自動以第一個區間的元素數量推斷出來,調用者必須保證這些區間的有效性。
STL算法採用覆蓋模式而非安插模式,因此調用者必須保證目標區間擁有足夠的元素空間,固然你也能夠運用特殊的安插型迭代器將覆蓋模式改變爲安插模式。

(3)尾詞_if:若是算法有兩種形式,參數個數都相同,但第一形式的參數要求傳遞一個值,第二形式的參數要求傳遞一個函數或仿函數,那麼尾詞_if就派上了用場,無尾詞的那個要求傳遞數值,有尾詞的那個要求傳遞函數或仿函數。不過並不是全部「要求傳遞仿函數」的算法都有尾詞_if,若是算法以額外參數來接受這樣的函數或仿函數,那麼不一樣版本的算法就能夠採用相同的命名。
尾詞_copy:這個尾詞用來表示在此算法中,元素不光被操做,還會被複制到目標區間。

(4)for_each()算法:
UnaryProc for_each (InputIterator beg, InputIterator end, UnaryProc op);
1對區間[beg, end)中的每個元素調用op(elem)
2返回op(已在算法內部被變更過)的一個副本
3op的任何返回值都會被忽略
4op能夠變更元素
5複雜度:線性

(5)元素計數算法:
difference_type count (InputIterator beg, InputIterator end, const T& value);
difference_type count_if (InputIterator beg, InputIterator end, UnaryPredicate op);
1第一形式會計算區間[beg, end)中的元素等於value的元素個數
2第二形式會計算區間[beg, end)中令如下一元判斷式結果爲true的元素個數:op(elem)
3返回值型別爲difference_type,是表現迭代器間距的型別
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6關聯式容器(set/multiset,map/multimap)提供了一個等效的成員函數count()用來計算等於某個value或key的元素個數
7時間複雜度:線性

(6)最大最小值算法:
InputIterator min_element (InputIterator beg, InputIterator end);
InputIterator min_element (InputIterator beg, InputIterator end, CompFunc op);
InputIterator max_element (InputIterator beg, InputIterator end);
InputIterator max_element (InputIterator beg, InputIterator end, CompFunc op);
1全部這些算法都返回區間[beg, end)中的最大或最小值的位置
2上述無op參數版本以operator<進行元素比較
3op用來比較兩個元素:op(elem1, elem2)若是第一個元素小於第二個元素,應當返回true
4若是存在多個最大或最小值,上述算法返回找到的第一個最大或最小值
5op不該該改動傳進去的參數
6時間複雜度:線性

(7)搜尋元素算法:
InputIterator find (InputIterator beg, InputIterator end, const T& value);
InputIterator find_if (InputIterator beg, InputIterator end, UnaryPredicate op);
1第一形式返回區間[beg, end)中的第一個「元素值等於value」的元素位置
2第二形式返回區間[beg, end)中令一元判斷式op(elem)結果爲true的第一個元素的位置
3若是沒有找到匹配元素,兩種形式都返回end
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6若是是已序區間,應使用lower_bound(),upper_bound(),equal_range()或binary_search()算法以獲取更高的性能
7關聯式容器(set/multiset,map/multimap)提供了一個等效的成員函數find(),擁有對數時間複雜度
8時間複雜度:線性

InputIterator search_n (InputIterator beg, InputIterator end, Size count, const T& value);
InputIterator search_n (InputIterator beg, InputIterator end, Size count, const T& value, BinaryPredicate op);
1第一形式返回區間[beg, end)中的第一組「連續count個元素值全等於value」的元素位置
2第二形式返回區間[beg, end)中的第一組「連續count個元素使op(elem, value)結果爲true」的元素位置
3若是沒有找到匹配元素,兩種形式都返回end
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6時間複雜度:線性

ForwardIterator1 search (ForwardIterator1 beg, ForwardIterator1 end, ForwardIterator2 searchBeg, ForwardIterator2 searchEnd);
ForwardIterator1 search (ForwardIterator1 beg, ForwardIterator1 end, ForwardIterator2 searchBeg, ForwardIterator2 searchEnd, BinaryPredicate op);
1兩種形式都返回區間[beg, end)內「和區間[searchBeg, searchEnd)徹底吻合」的第一個子區間內的第一個元素位置
2第一形式中,子區間元素必須徹底等於[searchBeg, searchEnd)的元素
3第二形式中,子區間元素和[searchBeg, searchEnd)的對應元素必須使op(elem, searchElem)結果爲true
4若是沒有找到匹配子區間,兩種形式都返回end
5注意op在函數調用過程當中不該該改變自身狀態
6op不該該改動傳進來的參數
7時間複雜度:線性

ForwardIterator find_end (ForwardIterator beg, ForwardIterator end, ForwardIterator searchBeg, ForwardIterator searchEnd);
ForwardIterator find_end (ForwardIterator beg, ForwardIterator end, ForwardIterator searchBeg, ForwardIterator searchEnd, BinaryPredicate op);
1兩種形式都返回區間[beg, end)內「和區間[searchBeg, searchEnd)徹底吻合」的最後一個子區間內的第一個元素位置
2第一形式中,子區間元素必須徹底等於[searchBeg, searchEnd)的元素
3第二形式中,子區間元素和[searchBeg, searchEnd)的對應元素必須使op(elem, searchElem)結果爲true
4若是沒有找到匹配子區間,兩種形式都返回end
5注意op在函數調用過程當中不該該改變自身狀態
6op不該該改動傳進來的參數
7時間複雜度:線性

ForwardIterator find_first_of (ForwardIterator1 beg, ForwardIterator1 end, ForwardIterator2 searchBeg, ForwardIterator2 searchEnd);
ForwardIterator find_first_of (ForwardIterator1 beg, ForwardIterator1 end, ForwardIterator2 searchBeg, ForwardIterator2 searchEnd, BinaryPredicate op);
1第一形式返回第一個「既在區間[beg, end)中出現,也在區間[searchBeg, searchEnd)中出現」的元素位置
2第二形式返回區間[beg, end)中的第一個這樣的元素:他和區間[searchBeg, searchEnd)內的每個元素進行op(elem, searchElem)結果都爲ture
3若是沒有找到匹配元素,兩種形式都返回end
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6你可使用逆向迭代器來搜尋最後一個這樣的元素
7時間複雜度:線性

InputIterator adjacent_find (InputIterator beg, InputIterator end);
InputIterator adjacent_find (InputIterator beg, InputIterator end, BinaryPredicate op);
1第一形式返回區間[beg, end)中的第一對「連續兩個相等元素」之中的第一個元素位置
2第二形式返回區間[beg, end)中的第一對「連續兩個元素均使op(elem, nextElem)結果爲true「的其中第一個元素位置
3若是沒有找到吻合元素,兩種形式都返回end
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6時間複雜度:線性

bool equal (InputIterator1 beg, InputIterator1 end, InputIterator2 cmpBeg);
bool equal (InputIterator1 beg, InputIterator1 end, InputIterator2 cmpBeg, BinaryPredicate op);
1第一形式判斷區間[beg, end)內的元素是否都和以cmpBeg開頭的區間內的元素相等
2第二形式判斷區間[beg, end)內的元素和以cmpBeg開頭的區間內的對應元素是否都能使op(elem, cmpElem)結果爲true
3調用者必須保證以cmpBeg開頭的區間具備足夠的元素
4當序列不相等時,若是想要了解其間的不一樣,應使用mismatch()算法
5注意op在函數調用過程當中不該該改變自身狀態
6op不該該改動傳進來的參數
7時間複雜度:線性

pair<InputIterator1, InputIterator2> mismatch (InputIterator1 beg, InputIterator1 end, InputIterator2 cmpBeg);
pair<InputIterator1, InputIterator2> mismatch (InputIterator1 beg, InputIterator1 end, InputIterator2 cmpBeg, BinaryPredicate op);
1第一形式返回區間[beg, end)和以cmpBeg開頭的區間之中的第一組兩兩相異的對應元素
2第二形式返回區間[beg, end)和以cmpBeg開頭的區間之中的第一組」使op(elem, cmpElem)結果爲false「的對應元素
3若是沒有找到相異點,就返回一個pair,以end和第二序列的對應元素組成。這並不意味着兩個序列相等,由於第二序列有可能包含更多的元素
4調用者必須保證以cmpBeg開頭的區間具備足夠的元素
5若是想要了解兩個序列是否相等,應使用equal()算法
6注意op在函數調用過程當中不該該改變自身狀態
7op不該該改動傳進來的參數
8時間複雜度:線性

bool lexicographical_compare (InputIterator1 beg1, InputIterator1 end1, InputIterator2 beg2, InputIterator2 end2);
bool lexicographical_compare (InputIterator1 beg1, InputIterator1 end1, InputIterator2 beg2, InputIterator2 end2, CompFunc op);
1兩種形式都用來判斷區間[beg1, end1)的元素是否小於區間[beg2, end2)的元素。所謂」小於「是指本着」字典次序「的意義
2第一形式使用operator<
3第二形式使用op(elem1, elem2)來判斷
4注意op在函數調用過程當中不該該改變自身狀態
5op不該該改動傳進來的參數
6時間複雜度:線性

(8)複製元素算法:
OutputIterator copy (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg);
BidirectionalIterator1 copy_backward (BidirectionalIterator1 sourceBeg,  BidirectionalIterator1 sourceEnd,  BidirectionalIterator2 destEnd);
1這兩個算法都將源區間[sourceBeg, sourceEnd)中的全部元素複製到以destBeg爲起點或以destEnd爲終點的目標區間裏去
2返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
3destBeg或destEnd不可處於[sourceBeg, sourceEnd)區間內
4copy()正向遍歷序列,copy_backward()逆向遍歷序列
5STL沒有所謂的copy_if()算法,因此若是要複製符合某特定準則的元素,請使用remove_copy_if()算法
6若是但願在複製過程當中逆轉元素次序,應該使用reverse_copy()
7調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
8若是想把容器內的全部元素賦值給另外一容器,應當使用assignment操做符(當兩個容器的型別相同時)或者使用容器的assign()成員函數(當兩個容器的型別不一樣時)
9若是但願在複製過程當中刪除某元素,請使用remove_copy()和remove_copy_if()算法
10若是但願在複製過程當中改變元素,請使用transform()或replace_copy()算法
11時間複雜度:線性

(9)轉換元素算法:
OutputIterator transform (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, UnaryFunc op);
1針對源區間[sourceBeg, sourceEnd)中的每個元素調用op(elem)並將結果寫到以destBeg爲起點的目標區間
2返回目標區間內最後一個被轉換的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
3調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
4sourceBeg和destBeg能夠相同,所以你可使用這個算法來變更某一序列內的元素
5若是想以某值來替換符合某一標準的元素,應使用replace()算法
6時間複雜度:線性

OutputIterator transform (InputIterator1 source1Beg, InputIterator1 source1End, InputIterator2 source2Beg, OutputIterator destBeg, BinaryFunc op);
1針對第一個源區間[source1Beg, source1End)以及從source2Beg開始的第二個源區間的對應元素調用op(source1Elem, source2Elem)並將結果寫到以destBeg起始的目標區間
2返回目標區間內最後一個被轉換的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
3調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
4調用者必須保證第二源區間有足夠空間(至少擁有和第一源區間相同的空間大小)
5source1Beg,source2Beg,destBeg能夠相同,所以你可讓元素本身和本身結合而後將結果覆蓋至某個序列
6時間複雜度:線性

(10)互換元素內容算法:
ForwardIterator2 swap_ranges (ForwardIterator1 beg1, ForwardIterator1 end1, ForwardIterator2 beg2);
1將區間[beg1, end1)內的元素和從beg2開始的區間內的對應元素互換
2返回第二區間中的最後一個被交換元素的下一位置
3調用者必須保證目標區間有足夠空間
4兩區間不得重疊
5若是要將相同型別的兩個容器內的所有元素互換,應使用swap()成員函數這樣一般更快
6時間複雜度:線性

(11)賦值算法:
void fill (ForwardIterator beg, ForwardIterator end, const T& newValue);
void fill_n (OutputIterator beg, Size num, const T& newValue);
1fill()將區間[beg, end)內的每個元素都賦予新值newValue
2fill_n()將從beg開始的前num個元素賦予新值newValue
3調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
4時間複雜度:線性

void generate (ForwardIterator beg, ForwardIterator end, Func op);
void generator_n (OutputIterator beg, Size num, Func op);
1generate()調用op產生新值並賦給區間[beg, end)內的每個元素
2generate_n()調用op產生新值並賦給以beg開始的區間內的前num個元素
3調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
4時間複雜度:線性

(12)替換元素算法:
void replace (ForwardIterator beg, ForwardIterator end, const T& oldValue, const T& newValue);
void replace_if (ForwardIterator beg, ForwardIterator end, UnaryPredicate op, const T& newValuedValue);
1replace()將區間[beg, end)內每個與oldValue相等的元素替換爲newValue
2replace_if()將區間[beg ,end)內每個令op(elem)爲true的元素替換爲newValue
3op不該該在函數調用過程當中改變自身狀態
4時間複雜度:線性

OutputIterator replace_copy (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, const T& oldValue, const T& newValue);
OutputIterator replace_copy_if (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, UnaryPredicate op, const T& newValue);
1replace_copy()是copy()和replace()的組合,它將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg開始的目標區間去,同時將與oldValue相等的全部元素替換成newValue
2replace_copy_if()是copy()和replace_if()的組合,它將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg開始的目標區間去,同時將令op(elem)結果爲true的全部元素替換成newValue
3倆個算法都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4op不該該在函數調用過程當中改變自身狀態
5時間複雜度:線性

(13)移除性算法:
ForwardIterator remove (ForwardIterator beg, ForwardIterator end, const T& value);
ForwardIterator remove_if (ForwardIterator beg, ForwardIterator end, UnaryPredicate op);
1remove()會移除區間[beg, end)中的每個與value相等的元素
2remove_if()會移除區間[beg, end)中的每個令op(elem)結果爲true的元素
3兩個算法都會返回變更後的序列的新邏輯終點(也就是最後一個未被移除元素的下一個位置)
4這些算法會把原來置於後面的未被移除元素向前移動,覆蓋被移除元素
5未被移除元素在相對次序上保持不變
6調用者在調用此算法後,應保證今後採用返回的新邏輯終點而再也不使用原始終點end
7op不該該在函數調用過程當中改變自身狀態
8因爲會發生元素變更,因此這些算法不可用於關聯式容器,關聯式容器提供了功能類似的成員函數erase()
9list提供了一個等效成員函數remove():不是從新賦值元素,而是從新安排指針
10時間複雜度:線性

OutputIterator remove_copy (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, const T& value);
OutputIterator remove_copy_if (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, UnaryPredicate op);
1remove_copy()是copy()和remove()的組合,它將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg開始的目標區間去,同時移除與value相等的全部元素
2remove_copy_if()是copy()和remove_if()的組合,它將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg開始的目標區間去,同時移除令op(elem)結果爲true的全部元素
3倆個算法都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4op不該該在函數調用過程當中改變自身狀態
5調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
6時間複雜度:線性

ForwardIterator unique (ForwardIterator beg, ForwardIterator end);
ForwardIterator unique (ForwardIterator beg, ForwardIterator end, BinaryPredicate op);
1兩個算法都會移除連續重複元素中的多餘元素
2第一形式將區間[beg, end)內的全部與前一個元素相等的元素移除,因此源區間必須先通過排序,才能使用這個算法
3第二形式將每個「位於元素e以後而且形成op(elem ,e)結果爲true」的全部elem元素移除,換言之此op並不是用來將元素和其本來的前一元素比較,而是將它和未被移除的前一元素比較
4兩種形式都返回被變更後的序列的新終點(最後一個未被移除的元素的下一個位置)
5兩個算法將本來位置在後的未被移除元素向前移動,覆蓋被移除元素
6未被移除元素在相對次序上保持不變
7調用者在調用此算法後,應保證今後採用返回的新邏輯終點而再也不使用原始終點end
8op不該該在函數調用過程當中改變自身狀態
9因爲會發生元素變更,因此這些算法不可用於關聯式容器
10list提供了一個等效成員函數unique():不是從新賦值元素,而是從新安排指針
11時間複雜度:線性

OutputIterator unique_copy (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg);
OutputIterator unique_copy (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, BinaryPredicate op);
1兩種形式都是copy()和unique()的組合
2二者都將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg開始的目標區間去,並移除重複元素
3倆個算法都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
5時間複雜度:線性

(14)變序性算法:
void reverse (BidirectionalIterator beg, BidirectionalIterator end);
OutputIterator reverse_copy (BidirectionalIterator sourceBeg, BidirectionalIterator sourceEnd, OutputIterator destBeg);
1reverse()將區間[beg, end)內的元素所有逆序
2reverse_copy()會將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg起始的目標區間,並在複製過程當中顛倒安置次序
3reverse_copy()返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
5list提供了一個等效成員函數reverse():不是從新賦值元素,而是從新安排指針
6時間複雜度:線性

void rotate (ForwardIterator beg, ForwardIterator newBeg, ForwardIterator end);
1將區間[beg, end)內的元素進行旋轉,執行後*newBeg成爲新的第一元素
2調用者必須保證newBeg是區間[beg, end)內的一個有效位置,不然會引起未定義的行爲
3時間複雜度:線性

void rotate_copy (ForwardIterator sourceBeg, ForwardIterator newBeg, ForwardIterator sourceEnd, OutputIterator destBeg);
1這是rotate()和copy()的組合
2將源區間[sourceBeg, sourceEnd)內的元素複製到以destBeg起始的目標區間中,同時旋轉元素使*newBeg成爲新的第一元素
3返回目標區間內最後一個被複制的元素的下一個位置
4調用者必須保證newBeg是區間[sourceBeg, sourceEnd)內的一個有效位置,不然會引起未定義的行爲
5調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
6源區間和目標區間不可重疊
7時間複雜度:線性

bool next_permutation (BidirectionalIterator beg, BidirectionalIterator end);
bool prev_permutation (BidirectionalIterator beg, BidirectionalIterator end);
1next_permutation()會改變區間[beg, end)內的元素次序,使它符合「下一個排列次序」
2prev_permutation()會改變區間[beg, end)內的元素次序,使它符合「上一個排列次序」
3若是元素得以排列成「正規」次序,則兩個算法都返回true。所謂正規次序,對next_permutation()而言爲升序,對prev_permutation()而言爲降序。所以若是要走遍全部排序,你必須先將全部元素(按升序或降序)排序,而後開始以循環方式調用prev_permutation()或next_permutation()直到算法返回false
4時間複雜度:線性

void random_shuffle (RandomAccessIterator beg, RandomAccessIterator end);
void random_shuffle (RandomAccessIterator beg, RandomAccessIterator end, RandomFunc& op);
1第一形式使用一個均勻分佈隨機數產生器來打亂區間[beg, end)內的元素次序
2第二形式使用op來打亂區間[beg, end)內的元素次序。算法內部會使用一個整數值來調用op:op(max),它應該返回一個大於零而小於max的隨機數但不包括max自身
3注意op是一個non-const reference,全部你不能夠將暫時數值或通常函數傳進去
4時間複雜度:線性

BidirectionalIterator partition (BidirectionalIterator beg, BidirectionalIterator end, UnaryPredicate op);
BidirectionalIterator stable_partition (BidirectionalIterator beg, BidirectionalIterator end, UnaryPredicate op);
1兩種算法將區間[beg, end)中的「形成op(elem)結果爲true」的元素向前端移動
2兩種算法都返回「令op(elem)結果爲false」的第一個元素位置
3二者差異爲不管元素是否符合給定的準則,stable_partition()會保持它們之間的相對次序
4你能夠運用此算法根據排序準則將全部元素分割爲兩部分,nth_element()具備相似能力
5op不該該在函數調用中改變自身狀態
6時間複雜度:partition()爲線性,stable_partition()當系統有足夠的內存時爲線性、不足時爲O(nlgn)

(15)排序算法:
void sort (RandomAccessIterator beg, RandomAccessIterator end);
void sort (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
void stable_sort (RandomAccessIterator beg, RandomAccessIterator end);
void stable_sort (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
1sort()和stable_sort()的上述第一形式使用operator<對區間[beg, end)內的全部元素進行排序
2sort()和stable_sort()的上述第二形式使用op(elem1, elem2)做爲排序準則對區間[beg, end)內的全部元素進行排序
3op不該該在函數調用中改變自身狀態
4sort()和stable_sort()的區別是後者保證相等元素的本來相對次序在排序後保持不變
5不能夠對list調用這些算法,由於list不支持隨機存取迭代器不過list提供了一個成員函數sort()
6時間複雜度:sort():O(nlgn),stable_sort()當系統有足夠的內存時爲O(nlgn)、不足時爲O(nlgn*lgn)

void partial_sort (RandomAccessIterator beg, RandomAccessIterator sortEnd, RandomAccessIterator end);
void partial_sort (RandomAccessIterator beg, RandomAccessIterator sortEnd, RandomAccessIterator end, BinaryPredicate op);
1上述第一形式使用operator<對區間[beg, end)內的全部元素進行排序,使區間[beg, sortEnd)內的元素處於有序狀態
2上述第二形式使用op(elem1, elem2)做爲排序準則對區間[beg, end)內的全部元素進行排序,使區間[beg, sortEnd)內的元素處於有序狀態
3op不該該在函數調用中改變自身狀態
4和sort()不一樣的是partial_sort()並不對所有元素進行排序:一旦第一個元素直至sortEnd之間的全部元素都排好次序就馬上中止,不會對剩餘的元素進行排序
5若是end和sortEnd相等,那麼partial_sort()會對整個序列進行排序,平均而言其效率不及sort(),不過最差狀況而言優於sort()
6時間複雜度:線性和O(nlgn)之間

RandomAccessIterator partial_sort_copy (InputIterator sourceBeg, InputIterator sourceEnd, RandomAccessIterator destBeg, RandomAccessIterator destEnd);
RandomAccessIterator partial_sort_copy (InputIterator sourceBeg, InputIterator sourceEnd, RandomAccessIterator destBeg, RandomAccessIterator destEnd, BinaryPredicate op);
1二者都是copy()和partial_sort()的組合
2它們將元素從源區間[sourceBeg, sourceEnd)複製到目標區間[destBeg, destEnd)同時排序
3被排序元素的數量是源區間和目標區間二者所含元素數量的最小值
4二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
5時間複雜度:線性和O(nlgn)之間

void nth_element (RandomAccessIterator beg, RandomAccessIterator nth, RandomAccessIterator end);
void nth_element (RandomAccessIterator beg, RandomAccessIterator nth, RandomAccessIterator end, BinaryPredicate op);
1兩種形式都對區間[beg, end)內的元素進行排序,使第n個位置上的元素就位,也就是說全部在位置n以前的元素小於等於它,全部位置在n以後的元素都大於等於它。這樣你就獲得了根據n位置上的元素分割開來的兩個子序列,第一子序列的元素通通小於第二子序列的元素。若是你只須要n個最大或最小的元素,但不要求它們必須已序,那麼這個算法就頗有用。
2上述第一形式使用operator<做爲排序準則
3上述第二形式使用op(elem1, elem2)做爲排序準則
4op不該該在函數調用中改變自身狀態
5時間複雜度:線性

(16)Heap算法:
void make_heap (RandomAccessIterator beg, RandomAccessIterator end);
void make_heap (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
1兩種形式都將[beg, end)內的元素轉化爲heap
2第二形式將op(elem1, elem2)視爲排序準則
3只有在多於一個元素的狀況下才有必要使用這些函數來處理heap
4時間複雜度:線性

void push_heap (RandomAccessIterator beg, RandomAccessIterator end);
void push_heap (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
1兩種形式都將end以前的最後一個元素加入本來就是個heap的[beg, end-1)區間內使整個區間[beg, end)成爲一個heap
2第二形式將op(elem1, elem2)視爲排序準則
3調用者必須保證進入函數時,區間[beg, end-1)內的元素本來已造成一個heap,而新元素緊跟其後
4時間複雜度:對數

void pop_heap (RandomAccessIterator beg, RandomAccessIterator end);
void pop_heap (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
1以上兩種形式都將heap[beg, end)內的最高元素也就是第一個元素移動到最後的位置上,並將剩餘區間[beg, end-1)內的元素組織起來成爲一個新heap
2第二形式將op(elem1, elem2)視爲排序準則
3調用者必須保證進入函數時,區間[beg, end)內的元素本來已造成一個heap,而新元素緊跟其後
4時間複雜度:對數

void sort_heap (RandomAccessIterator beg, RandomAccessIterator end);
void sort_heap (RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op);
1以上兩種形式都將heap[beg, end)轉換爲一個已序序列
2第二形式將op(elem1, elem2)視爲排序準則
3此算法一結束,該區間就再也不是個heap了
4調用者必須保證進入函數時,區間[beg, end)內的元素本來已造成一個heap,而新元素緊跟其後
5時間複雜度:對數

(17)搜尋元素:
bool binary_search (ForwardIterator beg, ForwardIterator end, const T& value);
bool binary_search (ForwardIterator beg, ForwardIterator end, const T& value, BinaryPredicate op);
1兩種形式都用來判斷已序區間[beg, end)中是否含有和value等值的元素
2第二形式將op(elem1, elem2)視爲排序準則
3若是想得到被搜尋元素的位置,應使用lower_bound(),upper_bound()或equal_range()算法
4調用者必須保證進入算法之際該區間已序
5時間複雜度:若是搭配隨機存取迭代器則爲對數複雜度,不然爲線性

bool includes (InputIterator1 beg, InputIterator1 end, InputIterator2 searchBeg, InputIterator2 searchEnd);
bool includes (InputIterator1 beg, InputIterator1 end, InputIterator2 searchBeg, InputIterator2 searchEnd, BinaryPredicate op);
1兩種形式都用來判斷已序區間[beg, end)是否包含另外一個已序區間[searchBeg, searchEnd)中的每個元素。也就是說對於[searchBeg, searchEnd)中的每個元素,若是[beg, end)必有一個對應的相等元素那麼[searchBeg, searchEnd)確定是[beg, end)的子集
2第二形式將op(elem1, elem2)視爲排序準則
3調用者必須保證在進入算法之際兩區間都應該已經按照相同的排序準則排好序了
4時間複雜度:線性

ForwardIterator lower_bound (ForwardIterator beg, ForwardIterator end, const T& value);
ForwardIterator lower_bound (ForwardIterator beg, ForwardIterator end, const T& value, BinaryPredicate op);

ForwardIterator upper_bound (ForwardIterator beg, ForwardIterator end, const T& value);
ForwardIterator upper_bound (ForwardIterator beg, ForwardIterator end, const T& value, BinaryPredicate op);
1lower_bound()返回第一個「大於等於value」的元素位置,這是可插入「元素值爲value」且「不破壞區間[beg, end)已序性」的第一個位置
2upper_bound()返回第一個「大於value」的元素位置,這是可插入「元素值爲value」且「不破壞區間[beg, end)已序性」的最後一個位置
3若是不存在其值爲value的元素,上述算法都返回end
4op(elem1, elem2)視爲排序準則
5調用者必須保證在進入算法之際全部區間都應該已經按照排序準則排好序了
6若是要同時得到lower_bound()和upper_bound()的結果,請使用equal_range()
7關聯式容器分別提供等效成員函數,性能更好
8時間複雜度:若是搭配隨機存取迭代器則爲對數複雜度,不然爲線性

pair<ForwardIterator, ForwardIterator> equal_range (ForwardIterator beg, ForwardIterator end, const T& value);
pair<ForwardIterator, ForwardIterator> equal_range (ForwardIterator beg, ForwardIterator end, const T& value, BinaryPredicate op);
1兩種形式都返回與value相等的元素所造成的區間,在此區間內插入其值爲value的元素並不會破壞區間[beg, end)的已序性
2和下式等效:make_pair(lower_bound(……), upper_bound(……))
3第二形式將op(elem1, elem2)視爲排序準則
4調用者必須保證在進入算法之際兩區間都應該已經按照相同的排序準則排好序了
5關聯式容器分別提供等效成員函數,性能更好
6時間複雜度:若是搭配隨機存取迭代器則爲對數複雜度,不然爲線性

(18)合併元素:
OutputIterator merge (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg);
OutputIterator merge (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg, BinaryPredicate op);
1二者都將源區間[source1Beg, source1End)和[source2Beg, source2End)內的元素合併,使得以destBeg起始的目標區間內含兩個源區間的全部元素
2目標區間內的全部元素都將按順序排列
3二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4第二形式將op(elem1, elem2)視爲排序準則
5源區間沒有任何變化
6調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
7list提供了一個等效成員函數merge()
8根據標準調用者應當確保兩個源區間一開始都是已序,然而在大部分實做版本中上述算法能夠將兩個無序的源區間內的元素合併到一個無序的目標區間中,不過要考慮到這樣的移植性
9目標區間和源區間不得重疊
10若是你要確保兩個源區間中都存在的元素在目標區間中只出現一次,請使用set_union()
11若是你要得到同時存在於兩個源區間的全部元素,請使用set_intersection()
12時間複雜度:線性

OutputIterator set_union (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg);
OutputIterator set_union (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg, BinaryPredicate op);
1二者都將源區間[source1Beg, source1End)和[source2Beg, source2End)內的元素合併,獲得以destBeg起始的目標區間——這個區間內含的元素要不來自第一源區間,要不就來自第二源區間,或是同時來自兩個區間
2同時出現於兩個源區間內的元素在並集區間中將只出現一次。不過若是原來的某個源區間內本來就存在重複元素,則目標區間也會有重複元素,重複的個數是兩個源區間內的重複個數的較大值
3二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4第二形式將op(elem1, elem2)視爲排序準則
5源區間沒有任何變化
6調用者應當確保兩個源區間一開始都是已序
7調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
8目標區間和源區間不得重疊
9若想獲得兩個源區間的所有元素,應使用merge()
10時間複雜度:線性
11目標區間內的全部元素都按順序排列

OutputIterator set_intersection (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg);
OutputIterator set_intersection (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg, BinaryPredicate op);
1二者都將源區間[source1Beg, source1End)和[source2Beg, source2End)內的元素合併,獲得以destBeg起始的目標區間——這個區間內含的元素不但存在於第一源區間,也存在於第二源區間
2若是原來的某個源區間內本來就存在重複元素,則目標區間也會有重複元素,重複的個數是兩個源區間內的重複個數的較小值
3二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
4第二形式將op(elem1, elem2)視爲排序準則
5源區間沒有任何變化
6調用者應當確保兩個源區間一開始都是已序
7調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
8目標區間和源區間不得重疊
9目標區間內的全部元素都按順序排列
10時間複雜度:線性

OutputIterator set_difference (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg);
OutputIterator set_difference (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg, BinaryPredicate op);
1二者都將源區間[source1Beg, source1End)和[source2Beg, source2End)內的元素合併,獲得以destBeg起始的目標區間——這個區間內含的元素只存在於第一源區間,不存在於第二源區間
2目標區間內的全部元素都按順序排列
3若是原來的某個源區間內本來就存在重複元素,則目標區間也會有重複元素,重複的個數是第一源區間內的重複個數減去第二源區間內的相應重複個數,若是第二源區間內的重複個數大於第一源區間內的相應重複個數,則目標區間內的對應重複個數將會是零
4二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
5第二形式將op(elem1, elem2)視爲排序準則
6源區間沒有任何變化
7調用者應當確保兩個源區間一開始都是已序
8調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
9目標區間和源區間不得重疊
10時間複雜度:線性

OutputIterator set_symmetric_difference (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg);
OutputIterator set_symmetric_difference (InputIterator source1Beg, InputIterator source1End, InputIterator source2Beg, InputIterator source2End, OutputIterator destBeg, BinaryPredicate op);
1二者都將源區間[source1Beg, source1End)和[source2Beg, source2End)內的元素合併,獲得以destBeg起始的目標區間——這個區間內含的元素或存在於第一源區間,或存在於第二源區間,但不一樣時存在於兩個源區間
2目標區間內的全部元素都按順序排列
3若是原來的某個源區間內本來就存在重複元素,則目標區間也會有重複元素,重複的個數是兩個源區間內的對應重複元素的個數差值
4二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
5第二形式將op(elem1, elem2)視爲排序準則
6源區間沒有任何變化
7調用者應當確保兩個源區間一開始都是已序
8調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
9目標區間和源區間不得重疊
10時間複雜度:線性

void inplace_merge (BidirectionalIterator beg1, BidirectionalIterator end1beg2, BidirectionalIterator end2);
void inplace_merge (BidirectionalIterator beg1, BidirectionalIterator end1beg2, BidirectionalIterator end2, BinaryPredicate op);
1二者都是將已源區間[beg1, end1beg2)和[end1beg2, end2)的元素合併,使區間[beg1, end2)成爲二者之總和(且造成已序)
2時間複雜度:內存足夠爲線性不然爲O(nlgn)

(19)數值算法:
運用數值算法須要包含頭文件:#include<numeric>

T accumulate (InputIterator beg, InputIterator end, T initValue);
T accumulate (InputIterator beg, InputIterator end, T initValue, BinaryFunc op);
1第一形式計算initValue和區間[beg, end)內的全部元素總和,具體地說它針對每個元素調用initValue+=elem
2第二形式計算initValue和區間[beg, end)內每個元素進行op運算的結果,具體地說它針對每個元素調用initValue=op(initValue, elem)
3若是序列爲空則二者都返回initValue
4時間複雜度:線性

T inner_product (InputIterator1 beg1, InputIterator1 end1,InputIterator2 beg2, T initValue);
T inner_product (InputIterator1 beg1, InputIterator1 end1,InputIterator2 beg2, T initValue, BinaryFunc op1, BinaryFunc op2);
1第一形式計算並返回[beg1, end1)區間和以beg2爲起始的區間的對應元素組(再加上initValue)的內積。具體地說針對兩區間內的每一組對應元素調用initValue=initValue+elem1*elem2
2第二形式將[beg1, end1)區間和以beg2爲起始的區間的對應元素組進行op2運算再和initValue進行op1運算並將結果返回。具體地說針對兩區間內的每一組對應元素調用initValue=op1(initValue, op2(elem1, elem2))
3若是第一區間爲空則二者都返回initValue
4調用者必須保證以beg2爲起始的區間內含足夠元素空間
5op1和op2都不得變更其參數內容
6時間複雜度:線性

OutputIterator partial_sum (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg);
OutputIterator partial_sum (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, BinaryFunc op);
1第一形式計算源區間[sourceBeg, sourceEnd)中的每一個元素的部分和,而後將結果寫入以destBeg爲起始的區間
2第二形式計算源區間[sourceBeg, sourceEnd)中的每一個元素和其先前全部元素進行op運算,而後將結果寫入以destBeg爲起始的區間
3對於數列a1 a2 a3 ……它們分別計算a1, a1+a2, a1+a2+a3,……和a1, a1 op a2, a1 op a2 op a3,……
4 二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
5第一形式至關於把一個相對值序列轉換爲一個絕對值序列,就此而言partial_sum()正好和adjacent_difference()互補
6源區間和目標區間能夠相同
7調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
8op不得變更其參數內容
9時間複雜度:線性

OutputIterator adjacent_difference (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg);
OutputIterator adjacent_difference (InputIterator sourceBeg, InputIterator sourceEnd, OutputIterator destBeg, BinaryFunc op);
1第一形式計算源區間[sourceBeg, sourceEnd)中的每一個元素和其緊鄰前驅元素的差值,而後將結果寫入以destBeg爲起始的區間
2第二形式計算源區間[sourceBeg, sourceEnd)中的每一個元素和其緊鄰前驅元素進行op運算,而後將結果寫入以destBeg爲起始的區間
3第一個元素只是被很單純的加以複製
4對於數列a1 a2 a3 a4……它們分別計算a1, a2-a1, a3-a2,a4-a3, ……和a1, a2 op a1, a3 op a2, a4 op a3,……
5 二者都返回目標區間內最後一個被複制的元素的下一個位置,也就是第一個未被覆蓋的元素的位置
6第一形式至關於把一個絕對值序列轉換爲一個相對值序列,就此而言partial_sum()正好和adjacent_difference()互補
7源區間和目標區間能夠相同
8調用者必須保證目標區間有足夠的空間,不然就得使用insert迭代器
9p不得變更其參數內容
時間複雜度:線性

轉載地址:http://www.cnblogs.com/zxh1210603696/p/3264992.htmlhtml

相關文章
相關標籤/搜索