STL容器
顺序容器:是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。
顺序容器包括:vector(向量)、list(列表)、deque(队列)。
容器类自动申请和释放内存,因此无需new和delete操作。
vector
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,
简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
使用vector,必须在你的头文件中包含下面的代码:
#include <vector>
属于std命名域的,因此需要通过命名限定,如下完成你的代码:
using std::vector;
vector vInts;
或者连在一起,使用全名
std::vector vInts;
初始化
vector // 创建一个空的vector。
vector c1(c2) // 复制一个vector
vector c(n) // 创建一个vector,含有n个数据,数据均已缺省构造产生
vector c(n, elem) // 创建一个含有n个elem拷贝的vector
vector c(beg,end) // 创建一个含有n个elem拷贝的vector
析构函数
c.~vector () // 销毁所有数据,释放内存
成员函数
c.begin() // 传回迭代器中的第一个数据地址。
c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
c.push_back(elem) // 在尾部加入一个数据。
c.clear() // 移除容器中所有数据。
c.empty() // 判断容器是否为空。
c.size() // 返回容器中实际数据的个数。
c1.swap(c2) // 将c1和c2元素互换。
swap(c1,c2) // 将c1和c2元素互换。同上操作。
c.capacity() // 返回容器中数据个数。
operator[] // 返回容器中指定位置的一个引用。
c.max_size() // 返回容器中最大数据的数量。
----------------------------------------------------------------------------------------
c.front() // 传回第一个数据。
c.back() // 传回最后一个数据,不检查这个数据是否存在。
c.assign(beg,end)c.assign(n,elem)//将[beg; end)区间中的数据赋值给c。将n个elem的拷贝赋值给c。
c.at(idx) //传回索引idx所指的数据,如果idx越界,抛出out_of_range。
c.erase(pos) // 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg,end) //删除[beg,end)区间的数据,传回下一个数据的位置。
get_allocator // 使用构造函数返回一个拷贝。
c.insert(pos,elem) // 在pos位置插入一个elem拷贝,传回新数据位置。
c.insert(pos,n,elem) // 在pos位置插入n个elem数据。无返回值。
c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值。
c.pop_back() // 删除最后一个数据。
c.rbegin() // 传回一个逆向队列的第一个数据。
c.rend() // 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) // 重新指定队列的长度。
c.reserve() // 保留适当的容量。
list
List定义
List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。使用时需要添加头文件
#include <list>
List初始化
list<int>lst1; //创建空list
list<int> lst2(5); //创建含有5个元素的list
list<int>lst3(3,2); //创建含有3个元素的list
list<int>lst4(lst2); //使用lst2初始化lst4
list<int>lst5(lst2.begin(),lst2.end()); //同lst4
List常用操作函数
Lst1.push_back() //在list的末尾添加一个元素
Lst1.push_front() //在list的头部添加一个元素
Lst1.clear() //删除所有元素
----------------------------------------------------
Lst1.assign() //给list赋值
Lst1.back() //返回最后一个元素
Lst1.begin() //返回指向第一个元素的迭代器
Lst1.empty() //如果list是空的则返回true
Lst1.end() //返回末尾的迭代器
Lst1.erase() //删除一个元素
Lst1.front() //返回第一个元素
Lst1.get_allocator() //返回list的配置器
Lst1.insert() //插入一个元素到list中
Lst1.max_size() //返回list能容纳的最大元素数量
Lst1.merge() //合并两个list
Lst1.pop_back() //删除最后一个元素
Lst1.pop_front() //删除第一个元素
Lst1.rbegin() //返回指向第一个元素的逆向迭代器
Lst1.remove() //从list删除元素
Lst1.remove_if() //按指定条件删除元素
Lst1.rend() //指向list末尾的逆向迭代器
Lst1.resize() //改变list的大小
Lst1.reverse() //把list的元素倒转
Lst1.size() //返回list中的元素个数
Lst1.sort() //给list排序
Lst1.splice() //合并两个list
Lst1.swap() //交换两个list
Lst1.unique() //删除list中重复的元素
deque
#include <deque>
deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。其余类似vector操作方法的使用。
顺序容器通用方法
添加元素
c.push_back(t) //在容器c的尾部添加值为t的元素。返回void 类型
c.push_front(t) //在容器c的前端添加值为t的元素。返回void 类型只适用于list和deque容器类型。
c.insert(p,t) //在迭代器p所指向的元素前面插入值为t的新元素。返回指向新添加元素的迭代器。
c.insert(p,n,t) //在迭代器p所指向的元素前面插入n个值为t的新元素。返回void 类型
c.insert(p,b,e) //在迭代器p所指向的元素前面插入由迭代器b和e标记的范围内的元素。返回 void 类型
容器大小操作
c.size() //返回容器c中元素个数。返回类型为 c::size_type
c.max_size() //返回容器c可容纳的最多元素个数,返回类型为c::size_type
c.empty() //返回标记容器大小是否为0的布尔值
c.resize(n) //调整容器c的长度大小,使其能容纳n个元素,如果n<c.size(),则删除多出来的元素。
c.resize(n,t) //调整容器c的长度大小,使其能容纳n个元素。所有新添加的元素值都为t
访问元素
c.back() //返回容器 c 的最后一个元素的引用。如果 c 为空,则该操作未定义
c.front() //返回容器 c 的第一个元素的引用。如果 c 为空,则该操作未定义
c[n] //返回下标为 n 的元素的引用。如果下标越界,则该操作未定义只适用于 vector 和 deque 容器
c.at(n) //返回下标为 n 的元素的引用。如果下标越界,则该操作未定义只适用于 vector 和 deque 容器
删除元素
c.erase(p) //删除迭代器p所指向的元素。返回一个迭代器,它指向被删除元素后面的元素。
c.erase(b,e) //删除迭代器b和e所标记的范围内所有的元素。返回一个迭代器,它指向被删除元素段后面的元素。
c.clear() //删除容器c内的所有元素。返回void。
c.pop_back() //删除容器c的最后一个元素。返回void。如果c为空容器,则该函数未定义。
c.pop_front() //删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义只适用于list或deque容器。
赋值和交换
c1 = c2 //删除容器c1的所有元素,然后将c2的元素复制给c1。c1和c2的类型(包括容器类型和元素类型)必须相同
c1.swap //(c2)交换c1和c2的内容,比赋值操作速度快。
c.assign //(b,e)将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器
c.assign //(n,t)将容器c重新设置为存储n个值为t的元素
关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。元素是有序的集合,默认在插入的时候按升序排列。
关联容器包括:map(集合)、set(映射)、multimap(多重集合)、multiset(多重映射)。
map
map容器提供一个键值对(key/value)容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。对于迭代器来说,可以修改实值,而不能修改key。Map会根据key自动排序。
map 是键-值对的集合。map 类型通常可理解为关联数组:可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。
初始化
#include <map>
map<k, v>m //创建一个名为m的空map对象,其键和值的类型分别为k和v
map<k, v>m(m2) //创建m2的副本m,m与m2必须有相同的键类型和值类型
map<k, v>m(b, e) //创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本,
//元素的类型必须能转换为pair<const k, v>。
在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering):可理解为键类型数据上的“小于”关系,虽然实际上可以选择将比较函数设计得更复杂。对于键类型,唯一的约束就是必须支持 < 操作符,至于是否支持其他的关系或相等运算,则不作要求。
方法
添加元素有两种方法:1、先用下标操作符获取元素,然后给获取的元素赋值 2、使用insert成员函数实现
下标操作添加元素:如果该键已在容器中,则 map 的下标运算与 vector 的下标运算行为相同:返回该键所关联的值。只有在所查找的键不存在时,map 容器才为该键创建一个新的元素,并将它插入到此 map 对象中。此时,所关联的值采用值初始化:类类型的元素用默认构造函数初始化,而内置类型的元素初始化为 0。
m insert(e) //e是一个用在m上的value_type 类型的值。如果键(e first不在m中,则插入一个值为e second
//的新元素;如果该键在m中已存在,则保持m不变。该函数返回一个pair类型对象,包含指向键为
//e first的元素的map迭代器,以及一个 bool 类型的对象,表示是否插入了该元素
-------------------------------------------------------------------------------------------
m insert(beg,end)//beg和end是标记元素范围的迭代器,其中的元素必须为m value_type 类型的键-值对。对于
//该范围内的所有元素,如果它的键在m中不存在,则将该键及其关联的值插入到m。返回void类型
-------------------------------------------------------------------------------------------
m insert(iter,e)//e是一个用在m上的 value_type 类型的值。如果键(e first)不在m中,则创建新元素,并以
//迭代器iter为起点搜索新元素存储的位置。返回一个迭代器,指向m中具有给定键的元素
遍历
map中使用下标存在一个很危险的副作用:如果该键不在 map 容器中,那么下标操作会插入一个具有该键的新元素。所以map 容器提供了两个操作:count 和 find,用于检查某个键是否存在而不会插入该键。
m count(k) //返回 m 中 k 的出现次数
m find(k) //如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。
删除
m erase(k) //删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数
m erase(p) //删除p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m end()。返回void
m erase(b,e) //从m中删除一段范围内的元素,该范围由迭代器对b和e标记。b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出在e所指向的元素之前。返回 void 类型
set
set的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就像一个集合一样。所有的操作的都是严格在logn时间之内完成,效率非常高。set和multiset的区别是:set插入的元素不能相同,但是multiset可以相同。Set默认自动排序。使用方法类似list。
begin() //返回指向第一个元素的迭代器
clear() //清除所有元素
count() //返回某个值元素的个数
empty() //如果集合为空,返回true
end() //返回指向最后一个元素的迭代器
equal_range() //返回集合中与给定值相等的上下限的两个迭代器
erase() //删除集合中的元素
find() //返回一个指向被查找到元素的迭代器
get_allocator() //返回集合的分配器
insert() //在集合中插入元素
lower_bound() //返回指向大于(或等于)某值的第一个元素的迭代器
key_comp() //返回一个用于元素间值比较的函数
max_size() //返回集合能容纳的元素的最大限值
rbegin() //返回指向集合中最后一个元素的反向迭代器
rend() //返回指向集合中第一个元素的反向迭代器
size() //集合中元素的数目
swap() //交换两个集合变量
upper_bound() //返回大于某个值元素的迭代器
value_comp() //返回一个用于比较元素间的值的函数
举个栗子:
#include<set>
#include<iostream>
using namespace std;
int main()
{
int i;
int arr[5] = {0,1,2,3,4};
set<int> iset(arr,arr+5);
iset insert(5);
cout<<"size:"<<iset size()<<endl;
cout<<"3 count = "<<iset count(3)<<endl;
iset erase(1);
set<int>::iterator ite1 = iset begin();
set<int>::iterator ite2 = iset end();
for(;ite1!=ite2;ite1++)
{
cout<<*ite1;
}
cout<<endl;
ite1 = iset find(3);
if(ite1!=iset end())
cout<<"3 found"<<endl;
ite1 = iset find(1);
if(ite1!=iset end())
cout<<"1 not found"<<endl;
}
参考链接:
https://www.jianshu.com/p/fe909c102c08
https://www.jb51.net/article/115201.htm
https://blog.csdn.net/u014465639/article/details/70241850