STL(Standard Template Library,標準模板庫)是惠普實驗室開發的一系列軟件的統稱。現然主要出如今C++中,但在被引入C++以前該技術就已經存在了很長的一段時間。ios
STL的從廣義上講分爲三類:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法經過迭代器能夠進行無縫地鏈接。幾乎全部的代碼都採 用了模板類和模板函數的方式,這相比於傳統的由函數和類組成的庫來講提供了更好的代碼重用機會。程序員
在C++標準中,STL 就位於各個 C++ 的頭文件中,即它並不是以二進制代碼的形式提供,而是以源代碼的形式提供。STL被組織爲下面的13個頭文 件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack> 和<utility>。算法
STL詳細的說六大組件:編程
STL六大組件的交互關係,容器經過空間配置器取得數據存儲空間,算法經過迭代器存儲容器中的內容,仿函數能夠協助算法完成不一樣的策略的變化,適配器能夠修飾仿函數windows
1)STL是C++的一部分,所以不用額外安裝什麼,它被內建在你的編譯器以內。數組
2)STL的一個重要特色是數據結構和算法的分離。儘管這是個簡單的概念,可是這種分離確實使得STL變得很是通用。數據結構
例如,在STL的vector容器中,能夠放入元素、基礎數據類型變量、元素的地址;框架
STL的sort()函數能夠用來操做vector,list等容器。數據結構和算法
3) 程序員能夠不用思考STL具體的實現過程,只要可以熟練使用STL就OK了。這樣他們就能夠把精力放在程序開發的別的方面。函數
4) STL具備高可重用性,高性能,高移植性,跨平臺的優勢。
5) 程序員能夠不用思考STL具體的實現過程,只要可以熟練使用STL就OK了。這樣他們就能夠把精力放在程序開發的別的方面。
6) 瞭解到STL的這些好處,咱們知道STL無疑是最值得C++程序員驕傲的一部分。每個C++程序員都應該好好學習STL。只有可以熟練使用STL的程序員,纔是好的C++程序員。
7) 總之:招聘工做中,常常遇到C++程序員對STL不是很是瞭解。大可能是有一個大體的映像,而對於在什麼狀況下應該使用哪一個容器和算法都感到比較茫然。STL是C++程序員的一項不可或缺的基本技能,掌握它對提高C++編程大有裨益。
幾乎能夠說,任何特定的數據結構都是爲了實現某種特定的算法。STL容器就是將運用最普遍的一些數據結構實現出來。
經常使用的數據結構:數組(array) , 鏈表(list), tree(樹),棧(stack), 隊列(queue), 集合(set),映射表(map), 根據數據在容器中的排列特性,這些數據分爲序列式容器和關聯式容器兩種。
序列式容器(Sequence containers)
每一個元素都有固定位置--取決於插入時機和地點,和元素值無關。如:Vector容器、Deque容器、List容器等。
關聯式容器(Associated containers)
元素位置取決於特定的排序準則,和插入順序無關。關聯式容器是非線性的樹結構,更準確的說是二叉樹結構。各元素之間沒有嚴格的物理上的順序關係,也就是說元素在容器中並無保存元素置入容器時的邏輯順序。關聯式容器另外一個顯著特色是:在值中選擇一個值做爲關鍵字key,這個關鍵字對值起到索引的做用,方便查找。Set/multiset容器 Map/multimap容器
數據結構 | 描述 | 實現頭文件 |
---|---|---|
向量(vector) | 連續存儲的元素 | <vector> |
列表(list) | 由節點組成的雙向鏈表,每一個結點包含着一個元素 | <list> |
雙隊列(deque) | 連續存儲的指向不一樣元素的指針所組成的數組 | <deque> |
集合(set) | 由節點組成的紅黑樹,每一個節點都包含着一個元素,節點之間以某種做用於元素對的謂詞排列,沒有兩個不一樣的元素可以擁有相同的次序 | <set> |
多重集合(multiset) | 容許存在兩個次序相等的元素的集合 | <set> |
棧(stack) | 後進先出的值的排列 | <stack> |
隊列(queue) | 先進先出的執的排列 | <queue> |
優先隊列(priority_queue) | 元素的次序是由做用於所存儲的值對上的某種謂詞決定的的一種隊列 | <queue> |
映射(map) | 由{鍵,值}對組成的集合,以某種做用於鍵對上的謂詞排列 | <map> |
多重映射(multimap) | 容許鍵對有相等的次序的映射 | <map> |
迭代器從做用上來講是最基本的部分,但是理解起來比前二者都要費力一些。軟件設計有一個基本原則,全部的問題均可以經過引進一個間接層來簡化, 這種簡化在STL中就是用迭代器來完成的。歸納來講,迭代器在STL中用來將算法和容器聯繫起來,起着一種黏和劑的做用。幾乎STL提供的全部算法都是通 過迭代器存取元素序列進行工做的,每個容器都定義了其自己所專有的迭代器,用以存取容器中的元素。
迭代器部分主要由頭文件<utility>,<iterator>和<memory>組 成。<utility>是一個很小的頭文件,它包括了貫穿使用在STL中的幾個模板的聲明,<iterator>中提供了迭代器 使用的許多方法,而對於<memory>的描述則十分的困難,它以不一樣尋常的方式爲容器中的元素分配存儲空間,同時也爲某些算法執行期間產生 的臨時對象提供機制,<memory>中的主要部分是模板類allocator,它負責產生全部容器中的默認分配器。
迭代器的種類:
迭代器 | 功能 | 描述 |
---|---|---|
輸入迭代器 | 提供對數據的只讀訪問 | 只讀,支持++、==、!= |
輸出迭代器 | 提供對數據的只寫訪問 | 只寫,支持++ |
前向迭代器 | 提供讀寫操做,並能向前推動迭代器 | 讀寫,支持++、==、!= |
雙向迭代器 | 提供讀寫操做,並能向前和向後操做 | 讀寫,支持++、–, |
隨機訪問迭代器 | 提供讀寫操做,並能以跳躍的方式訪問容器的任意數據,是功能最強的迭代器 | 讀寫,支持++、–、[n]、-n、<、<=、>、>= |
函數庫對數據類型的選擇對其可重用性起着相當重要的做用。舉例來講,一個求方根的函數,在使用浮點數做爲其參數類型的狀況下的可重用性確定比使 用整型做爲它的參數類性要高。而C++經過模板的機制容許推遲對某些類型的選擇,直到真正想使用模板或者說對模板進行特化的時候,STL就利用了這一點提 供了至關多的有用算法。它是在一個有效的框架中完成這些算法的——能夠將全部的類型劃分爲少數的幾類,而後就能夠在模版的參數中使用一種類型替換掉同一種 類中的其餘類型。
STL提供了大約100個實現算法的模版函數,好比算法for_each將爲指定序列中的每個元素調用指定的函數,stable_sort以你所指定的規則對序列進行穩定性排序等等。這樣一來,只要熟悉了STL以後,許多代碼能夠被大大的化簡,只須要經過調用一兩個算法模板,就能夠完成所須要 的功能並大大地提高效率。
算法部分主要由頭文件<algorithm>,<numeric>和<functional>組 成。<algorithm>是全部STL頭文件中最大的一個(儘管它很好理解),它是由一大堆模版函數組成的,能夠認爲每一個函數在很大程度上 都是獨立的,其中經常使用到的功能範圍涉及到比較、交換、查找、遍歷操做、複製、修改、移除、反轉、排序、合併等等。<numeric>體積很 小,只包括幾個在序列上面進行簡單數學運算的模板函數,包括加法和乘法在序列上的一些操做。<functional>中則定義了一些模板類, 用以聲明函數對象。
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> #include<algorithm> using namespace std; //STL 中的容器 算法 迭代器 void test01(){ vector<int> v; //STL 中的標準容器之一 :動態數組 v.push_back(1); //vector 容器提供的插入數據的方法 v.push_back(5); v.push_back(3); v.push_back(7); //迭代器 vector<int>::iterator pStart = v.begin(); //vector 容器提供了 begin()方法 返回指向第一個元素的迭代器 vector<int>::iterator pEnd = v.end(); //vector 容器提供了 end()方法 返回指向最後一個元素下一個位置的迭代器 //經過迭代器遍歷 while (pStart != pEnd){ cout << *pStart << " "; pStart++; } cout << endl; //算法 count 算法 用於統計元素的個數 int n = count(pStart, pEnd, 5); cout << "n:" << n << endl; } //STL 容器不僅僅能夠存儲基礎數據類型,也能夠存儲類對象 class Teacher { public: Teacher(int age) :age(age){}; ~Teacher(){}; public: int age; }; void test02(){ vector<Teacher> v; //存儲 Teacher 類型數據的容器 Teacher t1(10), t2(20), t3(30); v.push_back(t1); v.push_back(t2); v.push_back(t3); vector<Teacher>::iterator pStart = v.begin(); vector<Teacher>::iterator pEnd = v.end(); //經過迭代器遍歷 while (pStart != pEnd){ cout << pStart->age << " "; pStart++; } cout << endl; } //存儲 Teacher 類型指針 void test03(){ vector<Teacher*> v; //存儲 Teacher 類型指針 Teacher* t1 = new Teacher(10); Teacher* t2 = new Teacher(20); Teacher* t3 = new Teacher(30); v.push_back(t1); v.push_back(t2); v.push_back(t3); //拿到容器迭代器 vector<Teacher*>::iterator pStart = v.begin(); vector<Teacher*>::iterator pEnd = v.end(); //經過迭代器遍歷 while (pStart != pEnd){ cout << (*pStart)->age << " "; pStart++; } cout << endl; } //容器嵌套容器 難點 void test04() { vector< vector<int> > v; vector<int>v1; vector<int>v2; vector<int>v3; for (int i = 0; i < 5;i++) { v1.push_back(i); v2.push_back(i * 10); v3.push_back(i * 100); } v.push_back(v1); v.push_back(v2); v.push_back(v3); for (vector< vector<int> >::iterator it = v.begin(); it != v.end();it++) { for (vector<int>::iterator subIt = (*it).begin(); subIt != (*it).end(); subIt ++) { cout << *subIt << " "; } cout << endl; } } int main(){ //test01(); //test02(); //test03(); test04(); system("pause"); return 0; }
部份內容來自:
[【C/C++】STL詳解]:( https://blog.csdn.net/qq_42322103/article/details/99685797)