目录
vector容器
deque容器
stack容器
queue容器
List容器
set/multiset容器
map/multimap容器
STL-函数对象
STL 常用算法
与数组类似,也称为单端数组,vector可以动态扩展,空间满后,寻找更大的新空间,将原有数组拷贝到新空间
vector迭代器支持随机访问
vector构造函数
无参构造
通过输入迭代器的区间进行构造
通过n个elm进行构造
拷贝构造
vector赋值操作
vector& operator=(const vector &vec); //重载等号 assign(beg,end); //将[beg,end)的数据(此处还是指迭代器范围)拷贝赋值给本身 assign(n,elem); //将n个elem赋值给自身
assign()
理解为会把之前所有的值删除,然后赋参数列表里的值,与等号的作用等价
vector容量和大小
empty(); //判断容器是否为空 capacity(); //容器的容量 size(); //容器的大小 resize(); //重新指定大小,如果重新指定的大小比原来长,默认用0填充 //如果重新指定的大小比原来小,会删除超出部分元素
vector插入和删除
push_back(ele); pop_back(); insert(const_iterator pos,ele); //在迭代器位置插入元素 insert(const_iterator pos,count,ele);//在迭代器位置插入n个元素 erase(const_iterator pos);//删除指定位置 erase(const_iterator beg,const_iterator end);//删除指定范围,若范围为begin()和end(),等价于清空 clear();//清空容器内容
vector数据存取
at(int idx); //返回索引idx所指的数据 operator[]; //返回索引idx所指的数据 front(); //返回容器中第一个数据元素 back(); //返回最后一个元素
除了迭代器,也可以用 []
和 at()
等进行访问vector中的元素
vector互换容器
实现两个容器内元素进行互换
swap();
巧用swap()可以收缩内存:
vector(v).swap(v); //vector (v) 申请了一个匿名对象,内容用v拷贝 //匿名对象会在执行完语句后释放
vector预留空间
减少vector在动态扩展容量时的扩展次数
reserve(int space); //若数据量较大,预留空间可以减少动态扩展的次数
deque容器的基本概念
双端数组,也可以对头端进行插入删除操作
vector对于头部的数据插入删除效率低,需要移动大量元素
工作原理:
deque容器内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据
中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间
deque构造函数
deque
//默认构造
deque(beg,end);
//将迭代器[beg,end)区间中的元素拷贝给本身
deque(n,elem);
//构造函数将n个elem传入本身
deque(const deque &deq);
//拷贝构造函数
补充一点:函数参数是容器,且要加
const
修饰时,迭代器也要改为const_iterator
deque容器赋值操作
deque& operator=(const deque &deq);
//重载等号
assign(beg,end);
//通过另一个容器范围内的值进行赋值
assign(n,ele);
//n个ele元素进行赋值
assign()
理解为会把之前所有的值删除,然后赋参数列表里的值,与等号的作用等价
deque容器大小操作
deque.empty()
//判断容器是否为空
deque.size()
//返回容器的大小
deque.resize(n)
//重新指定大小,若比原来长,默认0填充
//若比原来短,相当于删除末尾元素
deque容器插入和删除
两端插入和删除
push_back(elem);
//尾插
push_front(elem);
//头插
pop_back()
//尾删
pop_front()
//头删
指定位置操作
insert(const_iterator pos,elem);
//pos位置插入一个elem元素的拷贝,返回新元素的位置(数据类型为迭代器类型)
insert(const_iterator pos,n,elem);
//pos位置插入n个elem元素的拷贝,无返回值
insert(pos,beg,end);
//pos位置插入[beg,end)区间的值,无返回值,相比vector多了此重载版本
clear();
//清空deque
erase(beg,end);
//删除[beg,end)区间内的值,返回下一个数据值位置
erase(pos);
//删除pos位置的值,返回下一个数据的位置
deque容器数据存取
at(int idx);
//返回索引idx所指的数据
operator[];
//重载[],返回索引idx所指的元素
front();
//返回容器中第一个数据元素
back();
//返回容器中最后一个数据元素
除了迭代器,也可以用 []
和 at()
等进行访问deque中的元素
deque容器排序操作
sort(iterator beg,iterator end);
//对区间内的元素进行排序
基本概念
先进后出,只有一个出口
栈不允许有遍历行为,只能访问栈顶元素
stack常用接口
构造函数
stack
//默认构造
stack(const stack &stk);
//拷贝构造函数
赋值操作
stack& operator=(const stack &stk);
//重载等号操作符
数据存取
push(elm);
//向栈顶添加元素
pop();
//移除栈顶元素
top();
//返回栈顶元素
大小操作:
empty();
//判断栈是否为空
size();
//返回栈的大小
队列(queue)是一种先进先出的数据结构,一端只能出队,一端只能入队,只能访问队头和队尾元素,不允许遍历行为
queue容器常用接口
构造函数
queue
//模板类实现,默认构造
queue(const queue &que);
//拷贝构造函数
赋值操作
queue& operator=(const queue &que);
//重载等号运算符
数据存取
push(elem);
//队尾添加元素
pop();
//移除队头元素
back();
//返回最后一个元素
front();
//返回第一个元素
大小操作
empty();
//判断是否为空
size();
//返回队列大小
基本概念
链表,使用非连续的内存地址,将数据进行链式存储,由一系列结点构成
STL中的List链表是双向循环链表,链表的存储方式并不是连续的内存空间,其迭代器只支持前移和后移,属于双向迭代器
插入和删除不会造成list 迭代器的失效,这在vector中不成立
list构造函数
list
//模板类实现,默认构造
list(beg,end);
//将迭代器[beg,end)区间 元素拷贝给自身
list(n,elem);
//将n个elem 拷贝给自身
list(const list &lst);
//拷贝构造函数
list赋值和交换
assign(beg,end);
//将迭代器[beg,end)范围内的数拷贝赋值给本身
assign(n,elem);
//赋值n个elem
list& operator=(const list &lst);
//重载等号
swap(lst);
//将lst与本身的元素互换,即使长度不同也可以互换
list大小操作
empty();
size();
resize(num);
//重新指定list的长度为num,若容器边长,则以默认值填充新位置
//若变短,则删除超出长度的元素
resize(num,elem);
list插入和删除
push_back(elem);
//尾插
push_front(elem);
//头插
pop_back()
//尾删
pop_front()
//头删
insert(const_iterator pos,elem);
//pos位置插入一个elem元素的拷贝,返回新元素的位置(数据类型为迭代器类型)
insert(const_iterator pos,n,elem);
//pos位置插入n个elem元素的拷贝,无返回值
insert(pos,beg,end);
//pos位置插入[beg,end)区间的值,无返回值,相比vector多了此重载版本
clear();
//清空
erase(beg,end);
//删除[beg,end)区间内的值,返回下一个数据值位置
erase(pos);
//删除pos位置的值,返回下一个数据的位置
remove(elem);
//删除容器中所有与elem值匹配的元素
list的迭代器不支持随机访问,只能++或--,因为双向链表只知道当前结点的前驱和后继,再往后的结点就得访问其他结点才知道
list数据存取
front();
//返回第一个元素
back();
//返回最后一个元素
无法重载[]
,也无法使用at()
,因为list不是连续的内存空间
list反转和排序
reverse();
//实现链表的反转
关于排序,list容器不能直接使用algorithm提供的
sort()
,所有不支持随机访问迭代器的容器,都不可以用标准算法
list内部提供了sort()
成员函数
sort()
默认为升序排序,若要为降序,需要提供比较器
bool myCompare(int v1,int v2) { return v1 > v2 ; }
例:自定义数据类型Person
,按照年龄升序,身高降序排列,需要提供:
bool comparePerson(Person &p1,Person &p2){ if(p1.m_Age==p2.m_Age) return p1.m_Height>p2.m_Height; return p1.m_Ageset/multiset容器
基本概念
所有元素都会在插入时自动被排序,set/multiset 属于关联式容器,底层用二叉树实现
set/multiset区别:
set不允许容器中有重复元素,multiset允许容器中有重复的元素
set构造和赋值
set
//默认构造st;
set(const set &st);
//拷贝构造
set& operator=(const set &st)
//重载等号操作符set插入数据只有
insert()
方式set大小和交换
size();
//返回容器中元素的数目
empty();
//判断是否为空
swap();
//交换两个集合容器set插入和删除
insert();
//插入元素
clear();
//清空
erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg,end);
//删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem);
//删除容器中值为elem的元素set查找和统计
find(key);
//查找key是否存在,若存在,返回该元素的迭代器,若不存在,返回set.end()
count (key);
//返回key的元素个数set和multiset区别
set插入数据的同时会返回插入结果,表示插入是否成功
multiset不会检测数据重复性,因此可以插入重复数据
pair对组创建
成对出现的数据,利用对组可以返回两个数据,使用对组不需要包含头文件
pair
p (value1,value2);
pair
p = make_pair(value1,value2); set容器排序
set默认排序规则为从小到大,利用仿函数可以改变排序规则
存放内置数据类型的情况:
//仿函数:class myCompare{public: bool operator()(int v1,int v2){ return v1>v2; } };//创建set容器setst; 存放自定义数据类型的情况:
class Person{public: Person(string name,int age) { this->m_Name=name; this->m_Age=age; } string m_Name; int m_Age;};//对于自定义数据类型,set容器需要通过仿函数指定排序规则class ComparePerson{public: bool operator()(const Person& p1,const Person& p2) { return p1.m_Age > p2.m_Age; //降序排列 }};setst; map/multimap容器
基本概念
map中所有元素都是pair,pair中第一个元素为key值(键值),起索引作用,第二个值为value(实值)
所有元素都会根据元素的键值自动排序
map/multimap是关联式容器,底层用二叉树实现,根据key可以快速找到value值
map不允许有重复的key值元素,multimap允许容器有重复key值元素
map构造和赋值
构造
map(T1,T2)mp;
//默认构造
map(const map &mp);
//拷贝构造赋值
map& operator=(const map &mp);
//重载等号map中所有数据都是成对出现,插入数据时要用对组
pair
map大小和交换
size();
//返回容器中元素的数目
empty();
//判断容器是否为空
swap();
//交换两个map容器map插入和删除
insert(elem)
//在容器中插入元素,此处元素是pair
clear();
//清空map
erase(pos);
//删除迭代器所指的元素,返回下一个元素的迭代器
erase(beg,end);
//删除区间[beg,end)的元素,返回下一个元素的迭代器
erase(key);
//删除容器中值为key的元素map内部重载了
[]
,可以用key通过中括号访问valuemapm;m.insert(make_pair(1,10));m.insert(pair (2,20));m.insert(map ::value_type(3,30)); map查找和统计
find(key);
//查找key是否存在,返回该键的元素的迭代器,弱不存在返回map.end()
count(key);
//统计key的元素个数map排序
改变排序顺序,或者对自定义数据类型排序,需要提供仿函数
STL-函数对象
概念
重载函数调用操作符
()
的类,其对象称为函数对象函数对象使用重载的
()
时,行为类似函数调用,也叫仿函数调用
函数对象在使用时,可以像普通函数一样调用,可以有参数,可以有返回值
//创建class Myadd{public: int operator()(int v1,int v2) { return v1+v2; }};//调用Myadd add;add(1,2);
函数对象超出普通函数的概念,函数对象可以有自己的状态
例:可以在类内添加count属性,统计函数对象调用次数
函数对象可以作为参数传递
谓词
谓词概念
返回
bool
类型的仿函数称为谓词,如果operator()接收一个参数,称为一元谓词,如果接收两个参数,称为二元谓词内建函数对象
STL内建了一些函数对象,包括:
算术仿函数
关系仿函数
逻辑仿函数
需要包含头文件
#include
算术仿函数
negate
是一元运算,其他都是二元运算negate
neg; int a=neg(50); //a的结果为-50 plus p; a=p(10,20); //a的结果为30 minus m; a=m(10,20); //a的结果为-10 关系仿函数
equal_to
,not_equal_to
,greater
,greater_equal
,less
,less_equal
逻辑仿函数
logical_and
,logical_or
,logical_not
STL 常用算法
常用遍历算法
for_each
//遍历容器
for_each(iterator beg,iterator end,_func)
;第三个参数可以是函数,也可以是函数对象
transform
//搬运容器到另一个容器中
transform(iterator beg1,ierator end1,ierator beg2,_func);
//参数:原迭代器begin,原迭代器end,目标迭代器begin,函数或函数对象
注意,目标容器需要提前开辟空间(使用
resize
)常用查找算法
find
//查找指定元素,返回指定元素的迭代器,未找到返回结束迭代器end()
find(iterator beg,iterator end,value);
find
查找自定义数据类型时,需要重载==
find_if
//按条件查找元素
find_if(iterator beg,iterator end,_Pred);
//参数:迭代器begin,迭代器end,谓词(bool类型仿函数)
adjacent_find
//查找相邻重复元素
adjacent_find(iterator beg,iterator end);
//beg 开始迭代器,end 结束迭代器 查找相邻重复元素,返回相邻元素的第一个位置的迭代器
binary_search
//查找指定元素是否存在
bool binary_search(iterator beg,iterator end,value);
//查找指定的元素,查到返回true,否则返回false
注意:
binary_search
只能用于有序序列
count
//统计元素的个数
count(iterator beg,iterator end,value);
//对于自定义数据类型需要重载
==
count_if //按条件统计元素个数
count_if(iterator beg,iterator end,_Pred)
//参数:迭代器begin,迭代器end,谓词(bool类型仿函数)
总结:对于自定义数据类型,需要重载符号,或提供一个谓词
常用排序算法
sort
//对容器内元素进行排序
sort(iterator beg,iterator end,_Pred);
//修改排序规则或对于自定义数据类型需要提供谓词
random_shuffle
//随机打乱容器中元素的顺序
random_shuffle(iterator beg,iterator end);
//如果要每次随机结果不同,需要加上随机数种子
merge
//将两个容器元素合并,并存储到另一容器,但两个容器必须是有序的(等同于归并排序的merge过程)
merge(ierator beg1,iterator end1,iterator beg2,ierator end2,ierator dest);
//beg1,end1,容器1的开始/结束迭代器
//beg2,end2,容器2的开始/结束迭代器
//dest,目标容器的开始迭代器
//dest容器需要使用
resize()
预先分配内存
reverse
//将容器内元素进行反转
reverse(iterator beg,iterator end);
常用拷贝和替换算法
copy
//容器内指定范围的元素拷贝到另一容器中
copy(iterator beg,iterator end,iterator dest);
//beg,end,容器的开始/结束迭代器
//dest,目标容器的开始迭代器
//dest容器需要使用
resize()
预先分配内存//相比于
copy
,transform
更灵活,可以自定义函数或者函数对象,在搬运时对数据进行操作
replace
//将容器内指定范围的旧元素修改为新元素
replace(iterator beg,iterator end,old_value,new_value);
//beg,end,容器的开始/结束迭代器
//old_value,new_value,旧元素/新元素
replace_if
//将区间内满足条件的元素,替换成指定元素
replace_if(iterator beg,iterator end,_Pred,newvalue)
//beg,end,容器的开始/结束迭代器
//_Pred 谓词
//newvalue 替换的新元素
swap
//替换两个同类型容器的元素常用算术生成算法
算术生成算法属于小型算法,使用时包含的头文件为
accumulate
//计算容器元素累计总和
accumulate(iterator beg,iterator end,value);
//beg,end,容器的开始/结束迭代器
//value,累加起始值,不需要起始值写0就可以
fill
//向容器内填充指定的元素
fill(iterator beg,iterator end,value);
//beg,end,容器的开始/结束迭代器
//value,填充的值
若是新建的容器,需要用
resize
预先指定其大小常用集合算法
set_intersection
//求两个集合的交集
iterator set_intersection(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);
//目标容器需要用
resize
提前开辟空间//
set_intersection
会返回交集end位置的迭代器
set_union
//求两个集合的并集
set_union(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);
//目标容器需要用
resize
提前开辟空间//
set_union
会返回并集end位置的迭代器
set_difference
//求两个容器的差集
set_difference(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest);
//目标容器需要用
resize
提前开辟空间//
set_diference
会返回并集end位置的迭代器