STL简介:
STL(Standard Template Library,标准模版库)以模板类和模版函数的形式为程序员提供了各种数据结构和算法的实现,程序员通过利用STL,可以在代码空间、执行时间和编码效率上获得极大的好处。
STL大致可以分为三大类:算法(algorithm)、容器(container)、迭代器(iterator)。
在C++标准中,STL被组织为以下的一组头文件(注意,是没有.h后缀的!):
algorithm/deque/functional/iterator/list/map/memory/numeric/queue/set/stack/utility/vector
一.队列(queue先进先出)
简介:先进先出(FIFO)的线性表
1.使用方法
头文件:#include <queue>
普通声明:queue <int> q;
特殊声明:(结构体)
struct node
{
int x,y;
};
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)
通过友元函数进行运算符重载:(优先队列默认从大到小排,所以 '<' 代表的是从大到小,比较特殊!)
struct node{
int x;
int y;
friend bool operator < (node n1,node n2){
return n1.x < n2.x; //"<"为从大到小排列,">"为从小到大排列。
}
};
三.双向队列(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默认从小到大排序。
迭代器:(容器都能使用)
set <int> ::iterator it; //定义前向迭代器
for(it=s.begin();it!=s.end();it++)
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>
使用前提:非降序列
举个栗子:
#include <iostream>
#include <algorithm>
using namespace std; int main(){
int a[]={,,,,};
int pos=lower_bound(a,a+,)-a;
cout<<pos<<endl;//pos=3,a[3]=5.
return ;
}
扩展使用:nlogn的(最长不降子序列),upper_bound()
注意:lower_bound()里面的前两个代表的分别是首地址和(首地址+数组长度)。
九.不定长数组(vector)
简介:vector是同一种对象的集合,每个对象都有一个对应的整数索引值。(简单来说就是不定长数组)
1.使用方法
头文件:#include <vector>
声明:vector <T> v;
2.基本操作
0.以下标的形式访问容器中的元素:v[i]
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可用于邻接表存图之类的。
十.对组(pair)
简介:表示一个二元组或元素对
1.使用方法
头文件:#include <pair>
声明:pair <T,T> p;
2.基本操作
访问第一个元素:p.first
访问第二个元素:p.second
十一.字符串(string)
简介:字符串是程序中经常要表达和处理的数据,我们通常采用字符数组或字符指针表示字符串。STL为我们提供了另一种使用起来更为便捷的字符串的表达方式:string。string类的定义在头文件<string>中。
1.使用方法
头文件:#include <string>
声明:string s;
2.基本操作
0.以下标的形式访问字符串中的元素:s[i]
1.字符串拼接:+
2.判断字符串s是否为空:s.empty()
3.返回字符串s里字符个数:s.size()或s.length()
4.截取s字符串中从i开始长度为len的子串:s.substr(i,len)
5.元素翻转:reverse(s.begin(), s.end());
6.查找第一个出现的字符串”cat“,返回其下标值,查不到返回 4294967295(npos),也可查找字符:s.find ( "cat " ) ;