一.队列（queue先进先出）

简介：先进先出（FIFO）的线性表

1.使用方法
    头文件：#include <queue>

    普通声明：queue <int> q;

    特殊声明：（结构体）

1 struct node
2 {
3     int x,y;
4 };
5 queue <node> q;
    （后面其他STL的声明以T代表数据类型）

2.基本操作

    1.push()   在末尾加入一个元素
    2.pop()     删除第一个元素
    3.front()    返回第一个元素 
    4.back()    返回最后一个元素 
    5.empty()  如果队列为空则返回真
    6.size()     返回队列中元素的个数

 

二.优先队列（priority_queue）

简介：优先队列具有最高级先出[first in,largest out]的行为特征

1.使用方法：

    头文件：#include <queue>

    声明：priority_queue <T> p_que;  /* 默认从大到小排序 */

               priority_queue < T,vector<T>,greater<T> >  /*从小到大排序,greater改成less为从大到小排序*/

               对于优先队列里元素为一个结构体类型，可对比较函数进行重载，使其按照某一个属性排序

2.基本操作

    1.push()    加入一个元素
    2.pop()     删除优先级最高的元素(队顶元素)
    3.top()      返回优先队列中优先级最高的元素(队顶元素)
    4.size()    返回优先队列中元素的个数
    5.empty() 如果优先队列为空则返回真

 优先队列时间复杂度：O（logn）

 通过友元函数进行运算符重载：（优先队列默认从大到小排，所以 '<' 代表的是从大到小，比较特殊！）

复制代码
1 struct node{  
2     int x;  
3     int y; 
4     friend bool operator < (node n1,node n2){  
5         return n1.x < n2.x;  //"<"为从大到小排列，">"为从小到大排列。
6     }   
7 }; 
复制代码
 

三.双向队列(deque)

简介：顾名思义，双向

1.使用方法

    头文件：#include <deque>

    声明：deque <T> d_q;

2.基本操作

    1.front()          返回第一个元素
    2.back()          返回最后一个元素
    3.pop_back()   删除尾部的元素
    4.pop_front()    删除头部的元素
    5.push_back()  在尾部加入一个元素
    6.push_front()   在头部加入一个元素
    7.size()             返回双向队列中元素的个数
    8.clear()            删除所有元素
    9.empty()          如果双向队列为空则返回真

 

四.集合(set)

简介：集合是实现了红黑树的平衡二叉检索树的一种数据结构。集合的互异性：同一个集合中的元素是互不相同的（敲黑板！）

1.使用方法

    头文件：#include <set>

    声明：set <T> s;

2.基本操作

    1.begin()      返回第一个元素的地址
    2.end()         返回最后一个元素的下一个位置的地址
    3.insert(key) 插入键值key
    4.erase(key) 删除键值key的值
    5.erase(it)     删除定位器it指向的值(指定地址)
    6.find(x)         返回找到x的位置,如果没找到返回end()的位置。
    7.count(key) 返回集合中key值的个数,其实就是判断有无的另一种方法。
    8.lower_bound（x）返回不小于x的第一个数的位置,在set自动排序的基础上去使用,非常方便。
    9.upper_bound（x）返回大于x的第一个数的位置,在set自动排序的基础上去使用,非常方便。
   10.clear()  删除所有元素
   11.empty() 如果集合为空则返回真
   12.size()    返回集合拥有的元素个数

  set默认从小到大排序。

迭代器：（容器都能使用）

1     set <int> ::iterator it; //定义前向迭代器    
2     for(it=s.begin();it!=s.end();it++)  
3     cout<<*it<<endl;
 

五.多重集合(multiset)

简介：性质和使用方法与set基本相同。特别的是多重集合无set的互异性。

1.使用方法

    头文件：#include <set>

    声明：multiset <T> m_s;

2.基本操作与set相同  

在multiset中的erase()的功能比较特别：（特好用的一个特性）

    erase(it) 删除定位器it指向的值(指定地址) /* it为地址 */

    erase(x) 删除集合里面所有的x /* x为具体的值 */

 

六.栈（stack后进先出）

简介：栈作为一种数据结构，是一种只能在一端进行插入和删除操作的特殊线性表。（以 ''后进先出'' 为原则）

1.使用方法

    头文件：#include <stack>

    声明：stack <T> sta;

2.基本操作 （栈基本操作虽然少,但是栈的特性超级无敌好用！）

    1.top() 返回最后一个元素
    2.pop() 删除最后一个元素
    3.push() 在末尾加入一个元素
    4.empty() 如果栈为空则返回真
    5.size() 返回栈中元素的个数

 

七.映射（map）

简介：map为从键（key）到值（value）的映射。并且map提供'' [] ''运算符,使得map可以像数组一样使用,因此map也称为''关联数组''。（非常好用的一种STL）

 举个栗子：例如可以用一个map<string, int> month_name 来表示“月份名字到月份编号”的映射，然后用month_name["July"] = 7 这样的方式来赋值。

1.使用方法

    头文件：#include <map>

    声明：map <T1,T2> m; 

2.基本操作

    1.insert() 插入元素

    2.empty() 如果映射为空则返回真 

    3.size() 返回映射中元素的个数

    4.erase() 删除元素

    5.clear() 清空

经验之谈：对于map，我基本上都拿来当数组用的。有时候数组下标无法定到题目中要求的，可以用映射解决。map的初始值为0或空。map <string,int> m;此时如果m["July"]没有赋值，那么m["July"]=0。同理map <int,string> m; m[1]没有赋值的话，m[1]='''';

八.lower_bound函数与upper_bound函数

简介：二分函数（ 时间复杂度 O（logn） ）

    lower_bound（）：前闭后开区间进行二分查找，返回大于或等于val的第一个元素位置

　 upper_bound（）：前闭后开区间进行二分查找，返回大于val的第一个元素位置

1.使用方法

    头文件：#include <algorithm>

    使用前提：非降序列

    举个栗子： 

复制代码
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main(){
 6     int a[5]={1,2,3,5,7};
 7     int pos=lower_bound(a,a+5,4)-a;
 8     cout<<pos<<endl;//pos=3,a[3]=5.
 9     return 0;
10 }
复制代码
    扩展使用：nlogn的（最长不降子序列），upper_bound()

    注意：lower_bound()里面的前两个代表的分别是首地址和尾地址

 

 九.不定长数组（vector）

简介：vector是同一种对象的集合，每个对象都有一个对应的整数索引值。（简单来说就是不定长数组）

1.使用方法

    头文件：#include <vector>

    声明：vector <T> v;

2.基本操作

    1.向量大小： vec.size();

    2.向量判空： vec.empty();

    3.末尾添加元素： vec.push_back();

    4.末尾删除元素： vec.pop_back();

    5.访问第一个元素： vec.front();

    6.访问最后一个元素： vec.back();

    7.元素翻转：reverse(vec.begin(), vec.end());

    8.sort(vec.begin(), vec.end()); //采用的是从小到大的排序

  vector可用于邻接表存图之类的。