STL中常用的數據結構:
[1] stack、queue默認的底層實現為deque結構。
[2] deque:用map管理多個size大小的連續內存塊,方便頭尾插入。
[3] vector:變長動態數組,每次增大1.5倍,刪除元素時不釋放空間。
[4] priority_queue底層默認采用vector向量O(nlogn)。
[5] list:雙向鏈表容器。
[6] slist:單向鏈表容器。
[7] bit_vector:一個bit位元素的序列容器,常用於硬件端口的控制。區別於vector<bool>重要特性是節省空間。
[8] set集合容器、multiset多重集合容器均采用紅黑樹實現,后者允許相同元素。
[9] map、multimap為映照容器,底層為紅黑樹。后者允許相同元素。
[10] hash_set哈希集合容器/hash_map哈希映照容器均采用hashtable。
[11] string基本字符序列容器。
1、C++ vector使用方法
1.1 基本操作
(1)頭文件#include<vector>
(2)創建vector對象,vector<int> vec;
(3)尾部插入數字:vec.push_back(a);
(4)使用下標訪問元素,cout<<vec[0]<<endl;
記住下標是從0開始的。
(5)使用迭代器訪問元素.
vector<int>::iterator it; for(it=vec.begin();it!=vec.end();it++) cout<<*it<<endl;
(6)插入元素:vec.insert(vec.begin()+i,a);
在第i+1個元素前面插入a;
(7)刪除元素:vec.erase(vec.begin()+2);
刪除第3個元素vec.erase(vec.begin()+i,vec.end()+j);
刪除區間[i,j-1];區間從0開始
(8)向量大小:vec.size();
(9)清空:vec.clear();
特別提示:這里有begin()
與end()
函數、front()
與back()
的差別
1.2重要說明
vector的元素不僅僅可以是int,double,string,還可以是結構體,但是要注意:結構體要定義為全局的,否則會出錯。
1.3算法
(1) 使用reverse將元素翻轉:需要頭文件
#include<algorithm> reverse(vec.begin(),vec.end());
將元素翻轉,即逆序排列!
(在vector中,如果一個函數中需要兩個迭代器,一般后一個都不包含)
(2)使用sort排序:需要頭文件
#include<algorithm>, sort(vec.begin(),vec.end());
(默認是按升序排列,即從小到大).
可以通過重寫排序比較函數按照降序比較,如下:
定義排序比較函數:
bool Comp(const int &a,const int &b) { return a>b; }
調用時:sort(vec.begin(),vec.end(),Comp)
,這樣就降序排序。
輸出Vector的中的元素
vector<float> vecClass; int nSize = vecClass.size(); //打印vecClass,方法一: for(int i=0;i<nSize;i++) { cout<<vecClass[i]<<" "; } cout<<endl;
需要注意的是:以方法一進行輸出時,數組的下表必須保證是整數。
//打印vecClass,方法二: for(int i=0;i<nSize;i++) { cout<<vecClass.at(i)<<" "; } cout<<endl;
//打印vecClass,方法三:輸出某一指定的數值時不方便 for(vector<float>::iterator it = vecClass.begin();it!=vecClass.end();it++) { cout<<*it<<" "; } cout<<endl;
2.list的用法void push_front(const T & val)
將 val 插入鏈表最前面void pop_front()
刪除鏈表最前面的元素void sort()
將鏈表從小到大排序void remove (const T & val)
刪除和 val 相等的元素remove_if
刪除符合某種條件的元素void unique()
刪除所有和前一個元素相等的元素void merge(list <T> & x)
將鏈表 x 合並進來並清空 x。要求鏈表自身和 x 都是有序的void splice(iterator i, list <T> & x, iterator first, iterator last)
在位置 i 前面插入鏈表 x 中的區間 [first, last),並在鏈表 x 中刪除該區間。鏈表自身和鏈表 x 可以是同一個鏈表,只要 i 不在 [first, last) 中即可
3.deque的用法
deque 也是順序容器的一種,同時也是一個可變長數組。要使用 deque,需要包含頭文件 deque。所有適用於 vector 的操作都適用於 deque。push_back
從尾部插入元素push_front
從頭部插入元素pop_back
從尾部刪除元素pop_front
從頭部刪除元素
它有兩種 vector 沒有的成員函數:void push_front (const T & val);
//將 val 插入容器的頭部void pop_front();
//刪除容器頭部的元素
distance
函數可以求出當前的迭代器指針it距離頭部的位置,也就是容器的指針
用法: distance(v1.begin(), it)
4.stack的用法size();
大小empty();
是否為空void pop();
彈出(即刪除)棧頂元素T & top();
返回棧頂元素的引用。通過此函數可以讀取棧頂元素的值,也可以修改棧頂元素void push (const T & x);
將 x 壓入棧頂
5.queue和priority_queue
queue
queue 就是“隊列”。隊列是先進先出的,和排隊類似。隊頭的訪問和刪除操作只能在隊頭進行,添加操作只能在隊尾進行。不能訪問隊列中間的元素。
queue 同樣也有和 stack 類似的 push
、pop
、top
函數。區別在於,queue 的 push 發生在隊尾,pop 和 top 發生在隊頭。
priority_queue
priority_queue 是“優先隊列”。它和普通隊列的區別在於,優先隊列的隊頭元素總是最大的——即執行 pop
操作時,刪除的總是最大的元素;執行 top
操作時,返回的是最大元素的引用。
priority_queue<int>
默認定義int類型的最大值隊列priority_queue<int, vector<int>, less<int>>
定義int型的最大值優先隊列priority_queue<int, vector<int>, greater<int>>
定義int型的最小值隊列
priority_queue 默認的元素比較器是 less 。也就是說,在默認情況下,要放入 priority_queue 的元素必須是能用“<”運算符進行比較的,而且 priority _queue 保證以下條件總是成立:對於隊頭的元素 x 和任意非隊頭的元素 y,表達式“x<y”必為 false。
priority_queue 的第三個類型參數可以用來指定排序規則。
priority_queue 隊頭的元素只能被查看或者修改,不能被刪除。
6.pair用法
pair實例化出來的類都有兩個成員變量,一個是 first, 一個是 second。
STL 中還有一個函數模板 make_pair,其功能是生成一個 pair 模板類對象。make_pair 的源代碼如下:
template <class T1, class T2> pair<T1, T2 > make_pair(T1 x, T2 y) { return ( pair<T1, T2> (x, y) ); }
下面的程序演示了 pair 和 make_pair 的用法。
#include <iostream> using namespace std; int main() { pair<int,double> p1; cout << p1.first << "," << p1.second << endl; //輸出 0,0 pair<string,int> p2("this",20); cout << p2.first << "," << p2.second << endl; //輸出 this,20 pair<int,int> p3(pair<char,char>('a','b')); cout << p3.first << "," << p3.second << endl; //輸出 97,98 pair<int,string> p4 = make_pair(200,"hello"); cout << p4.first << "," << p4.second << endl; //輸出 200,hello return 0; }
7.map的用法
基本操作:
C ++ Maps是一種關聯式容器,包含“關鍵字/值”對
begin()返回指向地圖右側的繼承器
clear()刪除所有元素
begin()返回指向地圖右側的繼承器
clear()刪除所有元素
count()返回指定元素出現的次數
empty()如果map為空則返回true
end()返回指向地圖末尾的繼承器
equal_range()返回特殊的的繼承器對
delete()刪除一個元素
find()發現一個元素
get_allocator()返回地圖的配置器
insert()插入元素
key_comp()返回比較元素key的函數
lower_bound()返回鍵值> =給定元素的第一個位置
max_size()返回可以容納的最大元素個數
rbegin()返回一個指向地圖尾部的逆向迭代器
rend()返回一個指向地圖頭部的逆向迭代器
size()返回地圖中元素的個數
swap()交換兩個地圖
upper_bound()返回鍵值>給定元素的第一個位置
value_comp()返回比較元素value的函數
用法示例
//通過pair<int, string>(1,”chenhua“) 構造pair元素 map1.insert(pair<int, string>(0,"zero")); //通過make_pair構造pair元素 map1.insert(make_pair(1,"m")); //通過value_type構造pair元素 map1.insert(map<int, string>::value_type(3,"ming")); //[]直接插入 map1[4] = "hello";
8、set的用法
C++的set容器,其中包含的元素是唯一的,而且是有序的。
C++的set容器,是按照順序插入的,不能在指定位置插入。
C++的set容器,其結構是紅黑二叉樹,插入數據的效率比vector快
創建集合的方式:
set<int>
創建默認的從小到大的int類型的集合set<int,less<int>>
創建一個從小打到大的int類型的集合set<int,greater<int>>
創建一個從大到小的int類型的集合
set提供了insert
和erase
函數,用來對元素進行插入和刪除操作。
set容器提供了多個函數用來查找元素:iterator find(const key_type& __k)
find函數查找元素為k的迭代器位置iterator lower_bound(const key_type& __k)
lower_bound函數查找小於等於元素k的迭代器位置iterator upper_bound(const key_type& __k)
upper_bound函數查找大於元素k的迭代器位置pair<iterator,iterator> equal_range(const key_type& __k)
equal_range函數返回一個pair類型,第一個屬性表示大於等於k的迭代器位置,第二個是大於k的迭代器位置
9.multiset容器
multiset容器,與set容器相似,但是multiset容器中的元素可以重復。另外,他也是自動排序的,容器內部的值不能隨便修改,因為有順序的。
multimap容器,與map容器的唯一區別是:multimap支持多個鍵值。