STL標準模板庫

STL的一個重要特點是數據結構和算法的分離
盡管這是個簡單的概念,但這種分離確實使得STL變得非常通用。例如,由于STL的sort()函數是完全通用的,你可以用它來操作幾乎任何數據集合,包括鏈表,容器和數組

STL另一個重要特性是它不是面向對象的
為了具有足夠通用性,STL主要依賴于模板而不是封裝,繼承和多態(虛函數)——OOP的三個要素。你在STL中找不到任何明顯的類繼承關系。這好像是一種倒退,但這正好是使得STL的組件具有廣泛通用性的底層特征。另外,由于STL是基于模板,內聯函數的使用使得生成的代碼短小高效

(重要知識點(10種):
序列式容器:(3種)vector、deque、list
關聯式容器:(4種)set、multiset、map、multimap
順序容器適配器:(3種)queue、priority_queue、stack)

STL中六大組件:

容器,迭代器,算法,仿函數,適配器,分配器

容器

STL中的容器有序列式容器,關聯式容器,容器適配器,位集和串包等
容器類自動申請和釋放內存,無需new和delete操作

(1)序列式容器:每個元素都有固定位置——取決于插入時機和地點,和元素值無關,vector、deque、list

vector(單向動態數組):將元素置于一個動態數組中加以管理,可以隨機存取元素(用索引直接存取),數組尾部添加或移除元素非??焖佟5窃谥胁炕蝾^部安插元素比較費時;
deque(雙向動態數組):是“double-ended queue”的縮寫,可以隨機存取元素(用索引直接存取),數組頭部和尾部添加或移除元素都非??焖?。但是在中部或頭部安插元素比較費時;
list(雙向鏈表):不提供隨機存?。ò错樞蜃叩叫璐嫒〉脑兀?,在任何位置上執行插入或刪除動作都非常迅速,內部只需調整一下指針;

(2)關聯式容器:元素位置取決于特定的排序準則,和插入順序無關,set、multiset、map、multimap

set/multiset:set內的相同數值的元素只能出現一次,multisets內可包含多個數值相同的元素,內部的元素依據其值自動排序,由二叉樹實現,便于查找;
map/multimap:map的元素是成對的鍵值/實值,map內的相同數值的元素只能出現一次,multimaps內可包含多個數值相同的元素,內部的元素依據其值自動排序,由二叉樹實現,便于查找;

迭代器

Iterator(迭代器):用于提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。或者這樣說可能更容易理解:Iterator模式是運用于聚合對象的一種模式,通過運用該模式,使得我們可以在不知道對象內部表示的情況下,按照一定順序(由iterator提供的方法)訪問聚合對象中的各個元素

迭代器的作用:能夠讓迭代器與算法不干擾的相互發展,最后又能無間隙的粘合起來,重載了*,++,==,!=,=運算符。用以操作復雜的數據結構,容器提供迭代器,算法使用迭代器;常見的一些迭代器類型:iterator、const_iterator、reverse_iterator和const_reverse_iterator

算法

算法部分主要由頭文件<algorithm>,<numeric>和<functional>組成。
<algorithm>是所有STL頭文件中最大的一個(盡管它很好理解),它是由一大堆模版函數組成的,可以認為每個函數在很大程度上都是獨立的,其中常用到的功能范圍涉及到比較、交換、查找、遍歷操作、復制、修改、移除、反轉、排序、合并等等。
<numeric>體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數,包括加法和乘法在序列上的一些操作。
<functional>中則定義了一些模板類,用以聲明函數對象。

STL中算法大致分為四類:
非可變序列算法:指不直接修改其所操作的容器內容的算法。
可變序列算法:指可以修改它們所操作的容器內容的算法。
排序算法:對序列進行排序和合并的算法、搜索算法以及有序序列上的集合操作。
數值算法:對容器內容進行數值計算。

適配器

標準庫提供了三種順序容器適配器:queue(FIFO隊列)、priority_queue(優先級隊列)、stack(棧)
要使用適配器,需要加入一下頭文件:

#include <stack>       //stack
#include <queue>       //queue、priority_queue
queue

默認順序容器:deque
可用順序容器:list、deque
說明:FIFO隊列,基礎容器必須提供push_front()運算

priority_queue

默認順序容器:vector
可用順序容器:vector、deque
說明:優先級隊列,基礎容器必須提供隨機訪問功能

stack

默認順序容器:deque
可用順序容器:vector、list、deque
說明:棧

定義適配器

1、初始化:stack<int> stk(dep);
2、覆蓋默認容器類型:stack<int,vector<int> > stk;

范例函數
queue/priority_queue范例函數:
queue<int> q; 
priority_queue<int> q;

兩者通用函數:

q.empty();  //判斷隊列是否為空
q.size();   //返回隊列長度
q.push(item);   //對于queue,在隊尾壓入一個新元素;對于priority_queue,在基于優先級的適當位置插入新元素

queue only:

q.front();  //返回隊首元素的值,但不刪除該元素
q.back();   //返回隊尾元素的值,但不刪除該元素

priority_queue only:

q.top();    //返回具有最高優先級的元素值,但不刪除該元素
stack范例函數:
stack<int> s;
stack< int, vector<int> > s2;  //覆蓋基礎容器類型,使用vector實現stk
s.empty();  //判斷stack是否為空,為空返回true,否則返回false
s.size();   //返回stack中元素的個數
s.pop();    //刪除棧頂元素,但不返回其值
s.top();    //返回棧頂元素的值,但不刪除此元素
s.push(item);   //在棧頂壓入新元素item

常用容器用法

序列式容器:vector、deque、list:每個元素都有固定位置——取決于插入時機和地點,和元素值無關
關聯式容器:set、multiset、map、multimap:元素位置取決于特定的排序準則,和插入順序無關

vector(begin,end || pop和push只有back)

1、構造函數

vector<type> vec:聲明一個元素類型為type的空vector
vector<type> vec(size):聲明一個元素類型為type的vector,元素個數為size
vector<type> vec(size, value):聲明一個元素類型為type的vector,元素個數為size,且值均為value
vector<type> obj(const vector&):復制構造函數
vector<type> obj(begin,end):復制[begin,end)區間數組的元素到vector中

2、增加函數

void push_back(const T& x):向量尾部增加一個元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一個元素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n個相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):
向量中迭代器指向元素前插入另一個相同類型向量的[first,last)間的數據

3、刪除函數

iterator erase(iterator it):刪除向量中迭代器指向元素
iterator erase(iterator first,iterator last):刪除向量中[first,last)中元素
void pop_back():刪除向量中最后一個元素
void clear():清空向量中所有元素

4、遍歷函數

reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量頭指針,指向第一個元素
iterator end():返回向量尾指針,指向向量最后一個元素的下一個位置
reverse_iterator rbegin():反向迭代器,指向最后一個元素
reverse_iterator rend():反向迭代器,指向第一個元素之前的位置

5、判斷函數

bool empty() const:判斷向量是否為空,若為空,則向量中無元素

6、大小函數

int size() const:返回向量中元素的個數
int capacity() const:返回當前向量張紅所能容納的最大元素值
int max_size() const:返回最大可允許的vector元素數量值

7、其他函數

void swap(vector&):交換兩個同類型向量的數據
void assign(int n,const T& x):設置向量中第n個元素的值為x
void assign(const_iterator first,const_iterator last):向量中[first,last)中元素設置成當前向量元素
補,待換位子
reverse(obj.begin(),obj.end()); 從頭到尾進行反轉

sort(obj.begin(),obj.end()); 從頭到尾進行排序,第三個參數不寫,默認升序
sort(obj.begin(),obj.end(),compare);寫參數時可按下方格式創建bool值
bool compare(int a,int b) 
 { 
    return a< b; //升序排列,如果改為return a>b,則為降序
 } 

8、看著清楚

1.push_back 在數組的最后添加一個數據
2.pop_back 去掉數組的最后一個數據
3.erase 刪除指針指向的數據項
4.clear 清空當前的vector
5.empty 判斷vector是否為空

6.at 得到編號位置的數據
7.begin 得到數組頭的指針
8.end 得到數組的最后一個單元+1的指針
9.front 得到數組頭的引用
10.back 得到數組的最后一個單元的引用
11.rbegin 將vector反轉后的開始指針返回(其實就是原來的end-1)
 12.rend 將vector反轉構的結束指針返回(其實就是原來的begin-1)

13.max_size 得到vector最大可以是多大
14.capacity 當前vector分配的大小
15.size 當前使用數據的大小
16.resize 改變當前使用數據的大小,如果它比當前使用的大,者填充默認值
17.reserve 改變當前vecotr所分配空間的大小

18.swap 與另一個vector交換數據
訪問方式

1、vector可以直接訪問(類似于數組的[ ]還有at( )方式和指針方式)
2、借由迭代器進行間接訪問

vector<int>::iterator it;//聲明一個迭代器,來訪問vector容器,作用:遍歷或者指向vector容器的元素 
for(it=vec.begin();it!=vec.end();it++)
{
    cout<<*it<<" ";
}
deque(front,back || pop和push有front和back)

雖然deque也提供Iterator,但它的迭代器并不是普通指針,其復雜度和vector不可同日而語。因此,我們應盡可能選擇使用vector而非deque。對deque進行的排序操作,為了最高效率,可將deque先完整復制到一個vector身上,將vector排序后(利用STL的sort算法),再復制回deque。

1、構造函數

#include<deque>  // 頭文件
deque<type> deq;  // 聲明一個元素類型為type的雙端隊列deque
deque<type> deq(size);  // 聲明一個類型為type、含有size個默認值初始化元素的的雙端隊列deque
deque<type> deq(size, value);  // 聲明一個元素類型為type、含有size個    value元素的雙端隊列deque
deque<type> deq(mydeque);  // 復制構造函數
deque<type> deq(first,last);  // 復制[first,last)區間數組的元素到deque中

2、

deq[ ]:用來訪問雙向隊列中單個的元素。
deq.front():返回第一個元素的引用。
deq.back():返回最后一個元素的引用。
deq.push_front(x):把元素x插入到雙向隊列的頭部。
deq.pop_front():彈出雙向隊列的第一個元素。
deq.push_back(x):把元素x插入到雙向隊列的尾部。
deq.pop_back():彈出雙向隊列的最后一個元素。

3、deque的一些特點

1.支持隨機訪問,即支持[ ]以及at(),但是性能沒有vector好。
2.可以在內部進行插入和刪除操作,但性能不及list。
3.deque兩端都能夠快速插入和刪除元素,而vector只能在尾端進行。
4.deque的元素存取和迭代器操作會稍微慢一些,因為deque的內部結構會多一個間接過程。
5.deque迭代器是特殊的智能指針,而不是一般指針,它需要在不同的區塊之間跳轉。
6.deque可以包含更多的元素,其max_size可能更大,因為不止使用一塊內存。
7.deque不支持對容量和內存分配時機的控制。
8.在除了首尾兩端的其他地方插入和刪除元素,都將會導致指向deque元素的任何pointers、references、iterators失效。不過,deque的內存重分配優于vector,因為其內部結構顯示不需要復制所有元素。
9.deque的內存區塊不再被使用時,會被釋放,deque的內存大小是可縮減的。不過,是不是這么做以及怎么做由實際操作版本定義。
10.deque不提供容量操作:capacity()和reverse(),但是vector可以。

訪問方式

1、deque同vector可以直接訪問(類似于數組的[ ]還有at( )方式和指針方式)
2、借由迭代器進行間接訪問

deque<int>::iterator it;//聲明一個迭代器,來訪問deque容器,作用:遍歷或者指向deque容器的元素 
deque<int>::iterator it;
for (it = deq.begin(); it != deq.end(); it++) 
{
    cout << *it << ' ';
}
list()

list是stl實現的雙向鏈表,與向量(vectors)相比, 它允許快速的插入和刪除,但是隨機訪問卻比較慢。使用時需要添加頭文件

1、構造函數

list<type> lst;  // 聲明一個元素類型為type的空list
list<type> lst(size);  // 聲明一個類型為type、含有size個默認值初始化元素的的list
list<type> lst(size, value);  //聲明一個元素類型為type、含有size個value元素的list
list<type> lst(mylist);  // 復制構造函數
list<type> lst(begin,end);  //復制[begin,end)區間數組的元素到deque中

2、常用函數

lst.assign() 給list賦值
lst.back() 返回最后一個元素
lst.begin() 返回指向第一個元素的迭代器
lst.clear() 刪除所有元素
lst.empty() 如果list是空的則返回true
lst.end() 返回末尾的迭代器
lst.erase() 刪除一個元素
lst.front() 返回第一個元素
lst.get_allocator() 返回list的配置器
lst.insert() 插入一個元素到list中
lst.max_size() 返回list能容納的最大元素數量
lst.merge() 合并兩個list

lst.pop_back() 刪除最后一個元素
lst.pop_front() 刪除第一個元素
lst.push_back() 在list的末尾添加一個元素
lst.push_front() 在list的頭部添加一個元素

lst.rbegin() 返回指向第一個元素的逆向迭代器
lst.remove() 從list刪除元素
lst.remove_if() 按指定條件刪除元素
lst.rend() 指向list末尾的逆向迭代器
lst.resize() 改變list的大小
lst.reverse() 把list的元素倒轉
lst.size() 返回list中的元素個數
lst.sort() 給list排序
lst.splice() 合并兩個list
lst.swap() 交換兩個list
lst.unique() 刪除list中相鄰重復的元素

lst.insert(++list1.begin(), 3, 9);在第一個元素后插入3個9

map/multimap
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,882評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,208評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,746評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,666評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,477評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,960評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,047評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,200評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,726評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,617評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,807評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,327評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,049評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,425評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,674評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,432評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,769評論 2 372

推薦閱讀更多精彩內容