C++ STL總結


  • STL概述

STL (Standard Template Library, 標准模板庫) 是惠普實驗室開發的一系列軟件的統稱。主要核心分為三大部分:容器(container)、算法(algorithm)和迭代器(iterator),另外還有容器適配器(container adaptor)和函數對象(functor)等其它標准組件。

  • 容器:

順序容器:

名稱

特性

vector

模擬的數據結構式動態數組,在內存中是連續儲存的,支持隨機存取,支持在尾部快速插入和刪除元素,搜索速度較慢

deque

稱為雙端隊列,在內存中的儲存方式是小片連續,每片之間用鏈表連接起來,支持隨機存取,支持在頭部和尾部快速插入和刪除元素,搜索速度較慢

list

稱為雙向鏈表,在內存中的儲存是不連續的,每個元素的內存之間用指針相連,不支持隨機存取(因為要從首或尾遍歷至指定位置),但是支持在任意位置快速插入和刪除元素,搜索速度最慢,擴展內存時無需復制和拷貝原元素

array

稱為靜態數組,在內存中是連續儲存的,支持隨機存取,不支持插入或刪除元素

forward_list

稱為前向鏈表,在內存中的儲存是不連續的,同list一樣支持在任意位置快速插入和刪除元素,不支持隨機存取,搜索速度也較慢,與list最大的區別在於其只能從頭部遍歷至尾部,不能反向遍歷,因此沒有保存后向指針,比list更省內存,插入和刪除元素比list稍慢。

注:紅色加粗的容器為C++11標准中新增的

關聯式容器:

名稱

特性

set

以紅黑樹實現,內存中是不連續儲存的,保存的是元素是唯一的鍵值且不可變,排列的方式根據指定的嚴格弱序排列,不支持隨機存取,搜索速度較快

multiset

與set基本一致,差別就在於允許保存重復鍵值

map

同樣以紅黑樹實現,保存的元素是一個pair類型{key, value},每個鍵值對應一個值,且鍵值唯一不可變,鍵值的排列方式根據指定的嚴格弱序排列,支持用key進行隨機存取,搜索速度較快

multimap

與map基本一致,差別在於鍵值可以重復

 

名稱

特性

unordered_set

以哈希表實現,內存中是不連續儲存的,保存的是元素是唯一的鍵值且不可變,無序的排列方式,不支持隨機存取,搜索速度比紅黑樹實現的set要快

unordered_multiset

與unordered_set基本一致,差別就在於允許保存重復鍵值

unordered_map

同樣以哈希表實現,保存的元素是一個pair類型{key, value},每個鍵值對應一個值,且鍵值唯一不可變,key值無序排列,支持用key進行隨機存取,搜索速度比紅黑樹實現的map要快

unordered_multimap

與unordered_map基本一致,差別在於鍵值可以重復

 

容器適配器:均可以用vector, list和deque來實現,沒有提供迭代器

名稱

特性

stack

默認用deque來實現數據結構的棧的功能

queue

默認用deque來實現數據結構的隊列的功能

priority_queue

默認用vector來實現,其中保存的元素按照某種嚴格弱序進行排列,隊首元素總是值最大的

 

空間適配器allocator:C++ Primer 5th 中文版P427

allocator模板類定義在頭文件memory.h中,它幫助我們將內存分配和對象構造分開來。它提供一種類型感知的內存分配方法,它分配的內存是原始的、未構造的。利用allocate方法分配一段內存,當利用allocator對象分配了內存以后,要再用construct方法來再這塊內存中構造指定類型的對象。當使用完這塊內存中的對象后,可以利用destroy方法來銷毀這個對象,這塊內存又變為原始的未構造的內存,可以再次在這塊內存中構造指定類型的對象。當使用完這塊內存后,要先銷毀其中保存的對象,再利用deallocate方法銷毀這塊內存。

 

  • 算法:

STL算法部分主要由頭文件<algorithm>,<numeric>,<functional>組成。要使用 STL中的算法函數必須包含頭文件<algorithm>,對於數值算法須包含<numeric>,<functional>中則定義了一些模板類,用來聲明函數對象。

STL中算法大致分為四類:

1)、非可變序列算法:指不直接修改其所操作的容器內容的算法。

2)、可變序列算法:指可以修改它們所操作的容器內容的算法。

3)、排序算法:包括對序列進行排序和合並的算法、搜索算法以及有序序列上的集合操作。

4)、數值算法:對容器內容進行數值計算。

以下對所有算法進行細致分類並標明功能:

<一>查找算法(13個)判斷容器中是否包含某個值

adjacent_find: 在iterator對標識元素范圍內,查找一對相鄰重復元素,找到則返回指向這對元素的第一個元素的ForwardIterator。否則返回last。重載版本使用輸入的二元操作符代替相等的判斷。

binary_search: 在有序序列中查找value,找到返回true。重載的版本實用指定的比較函數對象或函數指針來判斷相等。

count: 利用等於操作符,把標志范圍內的元素與輸入值比較,返回相等元素個數。

count_if: 利用輸入的操作符,對標志范圍內的元素進行操作,返回結果為true的個數。

equal_range: 功能類似equal,返回一對iterator,第一個表示lower_bound,第二個表示upper_bound。

find: 利用底層元素的等於操作符,對指定范圍內的元素與輸入值進行比較。當匹配時,結束搜索,返回指向該元素的Iterator。

find_end: 在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列的最后一次出現。找到則返回最后一對的第一個ForwardIterator,否則返回輸入的"另外一對"的第一個ForwardIterator。重載版本使用用戶輸入的操作符代替等於操作。

find_first_of: 在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列"中任意一個元素的第一次出現。重載版本中使用了用戶自定義操作符。

find_if: 使用輸入的函數代替等於操作符執行find。

lower_bound: 返回一個ForwardIterator,指向在有序序列范圍內的可以插入指定值而不破壞容器順序的第一個位置。重載函數使用自定義比較操作。

upper_bound: 返回一個ForwardIterator,指向在有序序列范圍內插入value而不破壞容器順序的最后一個位置,該位置標志一個大於value的值。重載函數使用自定義比較操作。

search: 給出兩個范圍,返回一個ForwardIterator,查找成功指向第一個范圍內第一次出現子序列(第二個范圍)的位置,查找失敗指向last1。重載版本使用自定義的比較操作。

search_n: 在指定范圍內查找val出現n次的子序列。重載版本使用自定義的比較操作。

<二>排序和通用算法(14個)提供元素排序策略

inplace_merge: 合並兩個有序序列,結果序列覆蓋兩端范圍。重載版本使用輸入的操作進行排序。

merge: 合並兩個有序序列,存放到另一個序列。重載版本使用自定義的比較。

nth_element: 將范圍內的序列重新排序,使所有小於第n個元素的元素都出現在它前面,而大於它的都出現在后面。重載版本使用自定義的比較操作。

partial_sort: 對序列做部分排序,被排序元素個數正好可以被放到范圍內。重載版本使用自定義的比較操作。

partial_sort_copy: 與partial_sort類似,不過將經過排序的序列復制到另一個容器。

partition: 對指定范圍內元素重新排序,使用輸入的函數,把結果為true的元素放在結果為false的元素之前。

random_shuffle: 對指定范圍內的元素隨機調整次序。重載版本輸入一個隨機數產生操作。

reverse: 將指定范圍內元素重新反序排序。

reverse_copy: 與reverse類似,不過將結果寫入另一個容器。

rotate: 將指定范圍內元素移到容器末尾,由middle指向的元素成為容器第一個元素。

rotate_copy: 與rotate類似,不過將結果寫入另一個容器。

sort: 以升序重新排列指定范圍內的元素。重載版本使用自定義的比較操作。

stable_sort: 與sort類似,不過保留相等元素之間的順序關系。

stable_partition: 與partition類似,不過不保證保留容器中的相對順序。

<三>刪除和替換算法(15個)

copy: 復制序列

copy_backward: 與copy相同,不過元素是以相反順序被拷貝。

iter_swap: 交換兩個ForwardIterator的值。

remove: 刪除指定范圍內所有等於指定元素的元素。注意,該函數不是真正刪除函數。內置函數不適合使用remove和remove_if函數。

remove_copy: 將所有不匹配元素復制到一個制定容器,返回OutputIterator指向被拷貝的末元素的下一個位置。

remove_if: 刪除指定范圍內輸入操作結果為true的所有元素。

remove_copy_if: 將所有不匹配元素拷貝到一個指定容器。

replace: 將指定范圍內所有等於vold的元素都用vnew代替。

replace_copy: 與replace類似,不過將結果寫入另一個容器。

replace_if: 將指定范圍內所有操作結果為true的元素用新值代替。

replace_copy_if: 與replace_if,不過將結果寫入另一個容器。

swap: 交換存儲在兩個對象中的值。

swap_range: 將指定范圍內的元素與另一個序列元素值進行交換。

unique: 清除序列中重復元素,和remove類似,它也不能真正刪除元素。重載版本使用自定義比較操作。

unique_copy: 與unique類似,不過把結果輸出到另一個容器。

<四>排列組合算法(2個)提供計算給定集合按一定順序的所有可能排列組合

next_permutation: 取出當前范圍內的排列,並重新排序為下一個字典序排列。重載版本使用自定義的比較操作。

prev_permutation: 取出指定范圍內的序列並將它重新排序為上一個字典序排列。如果不存在上一個序列則返回false。重載版本使用自定義的比較操作。

<五>算術算法(4個)

accumulate: iterator對標識的序列段元素之和,加到一個由val指定的初始值上。重載版本不再做加法,而是傳進來的二元操作符被應用到元素上。

partial_sum: 創建一個新序列,其中每個元素值代表指定范圍內該位置前所有元素之和。重載版本使用自定義操作代替加法。

inner_product: 對兩個序列做內積(對應元素相乘,再求和)並將內積加到一個輸入的初始值上。重載版本使用用戶定義的操作。

adjacent_difference: 創建一個新序列,新序列中每個新值代表當前元素與上一個元素的差。重載版本用指定二元操作計算相鄰元素的差。

<六>生成和異變算法(6個)

fill: 將輸入值賦給標志范圍內的所有元素。

fill_n: 將輸入值賦給first到first+n范圍內的所有元素。

for_each: 用指定函數依次對指定范圍內所有元素進行迭代訪問,返回所指定的函數類型。該函數不得修改序列中的元素。

generate: 連續調用輸入的函數來填充指定的范圍。

generate_n: 與generate函數類似,填充從指定iterator開始的n個元素。

transform: 將輸入的操作作用與指定范圍內的每個元素,並產生一個新的序列。重載版本將操作作用在一對元素上,另外一個元素來自輸入的另外一個序列。結果輸出到指定容器。

<七>關系算法(8個)

equal: 如果兩個序列在標志范圍內元素都相等,返回true。重載版本使用輸入的操作符代替默認的等於操作符。

includes: 判斷第一個指定范圍內的所有元素是否都被第二個范圍包含,使用底層元素的<操作符,成功返回true。重載版本使用用戶輸入的函數。

lexicographical_compare: 比較兩個序列。重載版本使用用戶自定義比較操作。

max: 返回兩個元素中較大一個。重載版本使用自定義比較操作。

max_element: 返回一個ForwardIterator,指出序列中最大的元素。重載版本使用自定義比較操作。

min: 返回兩個元素中較小一個。重載版本使用自定義比較操作。

min_element: 返回一個ForwardIterator,指出序列中最小的元素。重載版本使用自定義比較操作。

mismatch: 並行比較兩個序列,指出第一個不匹配的位置,返回一對iterator,標志第一個不匹配元素位置。如果都匹配,返回每個容器的last。重載版本使用自定義的比較操作。

<八>集合算法(4個)

set_union: 構造一個有序序列,包含兩個序列中所有的不重復元素。重載版本使用自定義的比較操作。

set_intersection: 構造一個有序序列,其中元素在兩個序列中都存在。重載版本使用自定義的比較操作。

set_difference: 構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。重載版本使用自定義的比較操作。

set_symmetric_difference: 構造一個有序序列,該序列取兩個序列的對稱差集(並集-交集)。

<九>堆算法(4個)

make_heap: 把指定范圍內的元素生成一個堆。重載版本使用自定義比較操作。

pop_heap: 並不真正把最大元素從堆中彈出,而是重新排序堆。它把first和last-1交換,然后重新生成一個堆。可使用容器的back來訪問被"彈出"的元素或者使用pop_back進行真正的刪除。重載版本使用自定義的比較操作。

push_heap: 假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向該函數前,必須先把元素插入容器后。重載版本使用指定的比較操作。

sort_heap: 對指定范圍內的序列重新排序,它假設該序列是個有序堆。重載版本使用自定義比較操作。

 

  • 迭代器(iterator):

1. STL容器中只有順序容器關聯容器支持迭代器遍歷,行為類似於指針,用於指向容器內的元素,並通過解引用*符號來獲取元素。

2. 所有容器的迭代器都支持==和!=運算符;一般都支持++和--運算符(forward_list不支持--運算符);除了無序關聯容器以外,其它容器的迭代器均支持<, <=, >, >=運算符。

3. 一個迭代器范圍由一對迭代器表示,第一個迭代器指向范圍內第一個元素,第二個迭代器指向范圍內最后一個元素的下一個位置,是一個左閉右開區間[begin, end)。如果begin和end相等,則范圍為空;如果begin和end不等,則范圍至少包含一個元素,且begin指向第一個元素;begin遞增若干次可以==end。

4. 每種容器都有指向首元素的begin()和指向尾后位置的end()迭代器,類型類似於vector<int>::iterator;另外還有對應的const版本的迭代器cbegin()和cend(),類型類似於vector<int>::const_iterator。

5. 反向迭代器,僅能反向迭代的容器支持。rbegin()指向末尾的第一個元素,rend()指向首元素的前一個位置,crbegin()和crend()分別為對應的const版本。類型為reverse_iterator以及其const版本const_reverse_iterator。

6. 所有容器支持的迭代器類型:

容器名稱

支持的迭代器類型

vector

隨機訪問迭代器

deque

隨機訪問迭代器

list

雙向迭代器

array

隨機訪問迭代器

forword_list

前向迭代器

stack

不支持

queue

不支持

priority_queue

不支持

set

雙向迭代器

multiset

雙向迭代器

map

雙向迭代器

multimap

雙向迭代器


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM