STL概述
c++标准模板库
——c++ Standard Template Libarary
-
STL是C++标准程序库的核心,深刻影响了标准程序库的整体结构
-
STL是泛型(generic)程序库,利用先进、高效的算法来管理数据
-
STL由一些可适应不同需求的集合类(collection class),以及在这些数据集合上操作的算法( algorithm)构成
-
STL内的所有组件都由模板(template)构成,其元素可以是任意类型
-
STL是所有C++编译器和所有操作系统平台都支持的一种库
STL六大部件
-
容器
-
分配器
-
算法
-
迭代器
-
适配器
-
仿函数

STL容器
分类
循序式容器 (sequence container)
排列次序取决于插入时机和位置
array(c++11)、vector、stack、queue、deque、priority_queue、list
关联式容器 (associative container)
排列次序取决于特定准则
set/multimap、map/multimap
STL容器的共通操作
初始化 (initialization)
容器<类型>对象名(参数)
-
产生一个空容器
list<int>a ;
vector<float>a;
deque<int>a;
stack<T>a;
-
以另一个容器元素为初值完成初始化
list<int>a;
...
vector<float>c(a.begin(),a.end());
-
以数组元素为初值完成初始化
int array[]={2,4,6,8};
...
set<int>c(array,array+sizeof(array)/sizeof(array[0]));
元素存取
| 操作 | 效果 |
|---|---|
| at(idx) | 返回索引idx所标识的元素的引用,进行越界检查 |
| operater[] (idx) | 返回索引idx所标识的元素的引用,不进行越界检查 |
| front() | 返回第一个元素的引用,不检查元素是否存在 |
| back() | 返回最后一个元素的引用,不检查元素是否存在 |
赋值操作
| 操作 | 效果 |
|---|---|
| c1=c2 | 将c2的全部元素赋值给c1 |
| c.assign(n,e) | 将元素e的n个拷贝赋值给c |
| c.assign(beg,end) | 将区间[begin;end]的元素赋值给c |
| c1.swap(c2) | 将c1和c2元素值互换 |
| swap(c1,c2) | 同上,全局函数 |
迭代器相关函数
| 操作 | 效果 |
|---|---|
| begin() | 返回一个迭代器,指向第一个元素 |
| end() | 返回一个迭代器,指向最后一个元素之后 |
| rbegin() | 返回一个逆向迭代器,指向逆向遍历的第一个元素 |
| rend() | 返回一个逆向迭代器,指向逆向遍历的最后一个元素 |
迭代器持续有效,除非:
-
删除或插入元素
-
容量变化而引起内存重新分配
插入(insert)函数
| 操作 | 效果 |
|---|---|
| c.insert(pos,e) | 在pos位置插入元素e的副本,并返回新元素位置 |
| c.insert(pos,n,e) | 在pos位置插入n个元素e的副本 |
| c.insert(pos,beg,end) | 在pos位置插入区间[beg;end]内所有元素的副本 |
| c.push_back(e) | 在尾部添加一个元素e的副本 |
移除( remove)元素操作
| 操作 | 效果 |
|---|---|
| c.pop_back() | 移除最后一个元素但不返回最后一个元素 |
| c.erase(pos) | 删除pos位置的元素,返回下一个元素的位置 |
| c.erase(beg,end) | 删除区间[beg;end]内所有元素,返回下一个元素的位置 |
| c.clear() | 移除所有元素,清空容器 |
| c.resize(num) | 将元素数量改为num(增加的元素用defalut构造函数产生,多余的元素被删除) |
| c.resize(num,e) | 将元素数量改为num(增加的元素是e的副本) |
容器
Vector
动态数组,运行时根据需要改变数组大小。
-
以数组形式存储,内存空间是连续的,索引可以在常数时间内完成;
-
但是在中间进行插入和删除操作,会造成内存块的拷贝


Stack 栈
特点:先进后出(FILO)
#include<stack> //头文件

Queue 队列
特点:先进先出 (FIFO)
#include<queue>//头文件

Pritrity_queue 优先队列
以某种排序准则(默认为less)管理队列中的元素
#include<queue>//头文件
-
优先队列:优先级最高的最先出列
-
队列和排序的完美结合,不仅可以存储数据,还可以价格这些数据按照设动的规则进行排序
-
每次的push和pop操作,优先队列都会动态调整,把优先级最高的元素放在前面
priority_queue<int,vector<int>,less<int> > q;//降序排列(默认)
priority_queue<int,vector<int>,greater<int> >g;//升序排列
priority_queue<double> i;//默认降序排列
q.top();//返回具有最高优先级的元素值,但不删除元素
q.pop();//删除最高优先级的元素
q.push(item);//插入新元素
struct Node{//结构体
int x,y;
//重载 "<"小于符号
bool operator < (const Node &a) const{
if(x!=a.x) return x<a.x;//按照x升序排列
else return y>a.y;//x相等时,按照y降序排序
}
};
priority_queue<Node> q;//调用
List 双向链表
内存空间不一定连续,通过指针来进行数据的访问,高效率的在任意地方进行插入和删除,插入、删除操作是常数时间;
list的元素可以是任意类型T,但是必须具备赋值和拷贝的能力;
#include <list>//头文件
list不支持随机存取,因此不提供下标操作符;
list和vector优缺点:
-
vector:插入和删除操作少,随机访问元素频繁
-
list:插入和删除操作频繁,随机访问少
构造、拷贝和析构
| 操作 | 效果 |
|---|---|
| list<T>c | 产生空的list |
| list<T>c1(c2) | 产生同类型的c1,并复制c2的所有元素 |
| list<T>c(n) | 利用类型T的默认构造函数和拷贝构造函数生成一个大小为n的list |
| list<T>c(n,e) | 产生一个大小为n的list,每个元素都是e |
| list<T>c(beg,end) | 产生一个list,以区间[beg;end]为元素初值 |
| ~list<T>() | 销毁所有元素并释放内存 |
非变动性操作
| 操作 | 效果 |
|---|---|
| c.size() | 返回元素个数 |
| c.empty() | 判断容器是否为空 |
| c.max_size() | 返回元素最大可能数量 |
| …… | …… |
特殊变动性操作
| 操作 | 效果 |
|---|---|
| c.unque | 移除重复元素,只留下一个 |
| c.unque(op) | 移除使op()结果为true的重复元素 |
| c1.splice(pos,c2,c2pos) | 将c2内c2pos所指元素转移到c1内的pos之前 |
| c1.splice(pos,c2,c2beg,c2end) | 将c2内[c2beg;c2end)区间内所有元素转移到c1的pos之前 |
迭代器(Iterator)
容器<类型> ::iterator
-
可遍历STL容器内全部或部分元素的对象
-
指出容器中的一个特定位置
-
迭代器的基本操作
| 操作 | 效果 |
|---|---|
| * | 返回当前位置上的元素值。如果该元素有成员,可以通过迭代器以operator->取用 |
| ++ | 将迭代器前进至下一元素 |
| ==和!= | 判断两个迭代器是否指向同一位置 |
| = | 为迭代器赋值 |
-
所有容器都提供两种迭代器
-
container::iterator 以“读/写”模式遍历元素
-
container::const_iterator 以“只读”模式遍历元素
-
迭代器分类
-
双向迭代器
-
可以双向行进,以递增运算前进或以递减运算后退,可以用 == 和 != 比较。
-
-
随机存取迭代器
-
除了具备双向迭代器的所有属性外,还具备随机访问能力;
-
可以对迭代器增加或减少一个偏移量,处理迭代器之间的距离或者使用 < 和 > 之类的关系运算符比较两个迭代器;
-
vector、deque和string 提供随机存取迭代器
-
stack、queue、priority_queueq不支持迭代器
-
Set 集合
STL中的set用二叉搜索树实现,集合中的每个元素只出现一次,且是排好序的;
访问元素的时间复杂度是O(logn)的;
| 例子 | 说明 |
|---|---|
| set<Type> A; | 定义 |
| A.insert(item); | 把item放进set |
| A.erase(item); | 删除元素item |
| A.clear(); | 清空set |
| A.empty(); | 判断是否为空 |
| A.size(); | 返回元素个数 |
| A.find(k); | 返回一个迭代器,指向键值k |
| A.lower_bound(k); | 返回一个迭代器,指向键值不小于k的第一个元素 |
| A.upper_bound(k); | 返回一个迭代器,指向键值大于k的第一个元素 |
Multiset 多重集合
与set最大区别:multiset可以插入重复的元素
如果删除,则相同的元素同时被删除
如果查找,返回该元素的迭代器的位置,如果相同则返回第一个元素的地址
其他使用与set基本类似
Map/Multimap
使用平衡二叉树管理元素
元素包含两部分(key,value),key 和 value 可以是任意类型
#include <map>//头文件
根据元素的key自动对元素排序
不能直接改变元素的key,可以通过operator[]直接存取元素值
map中不允许key相同的元素,multimap允许key相同并的元素
赋值方法
map<int,string> mapStudent;//定义//1) insert函数插入pair数据
mapStudent.insert(pair<int,string>(1,"student_one"));
//2) 数组方式插入数据
mapStudent[2]="student_two";map<int,string>::iterator iter; //定义迭代器
//循环输出
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<<iter->first<<" "<<iter->second<<endl;
}
iter.find(1);//查找元素
mapStudent.erase(iter);//迭代器删除
int n = mapStudent.erase(1);//关键字删除,删除成功返回1,否则返回0
mapStudent.erase(mapStudent.begin(),mapStudent.end());//成片删除
浙公网安备 33010602011771号