STL标准模板库
STL是 Standard Template Library 的缩写,中文称为标准模板库
由惠普实验室提供(使用了C++的模板语言封装的常用的数据结构和算法)
里面共有三类内容:
算法:以函数模板形式的常用算法:如:swap,max,min,find,sort
容器:类类模板实现了常用的数据结构,如:栈,队列,链式表,顺序表,红黑树
迭代器:它是容器的成员,用于帮助访问容器中的元素,使用方法类似于指针
常用的算法函数
#include <algorithm>
iterator find( iterator start, iterator end, const TYPE& val );
功能:顺序查找,
start:指向第一个元素的迭代器(指针)
end:指向最后一个元素的下一个位置的迭代器
val:待查找的关键数据
返回值:
在 [start,end) 范围内找到了val,返回该val的指针或者迭代器
找不到返回end
#include <algorithm>
void sort( iterator start, iterator end );
void sort( iterator start, iterator end, StrictWeakOrdering cmp );
功能:快速排序
start:指向第一个元素的迭代器(指针)
end:指向最后一个元素的下一个位置的迭代器
注意:排序的元素需要支持 < 运算符,否则要在后面提供比较的回调函数参数,格式如下:
bool cmp(const int& a,const int& b)
{
return a > b;
}
vector 向量容器:
#include <vector> //头文件,采用顺序结构存储数据,可以通过下标随机访问元素,因此也称为数组容器
构造函数:
vector( size_type num, const TYPE& val = TYPE() );
num:数组的长度
val:用于初始化所有元素,不给默认为0
vector( input_iterator start, input_iterator end );
功能:通过使用一组数据进行初始化向量容器
start:数据的第一个元素
end:最后一个元素的下一个位置
支持的运算符:
== != <= >= < > 会对容器进行整体比较,
根据字符串的比较规则进行比较(一个个元素按照字典序比较,一旦比较出结果就结束)
[] 让向量可以当做数组使用,一样不检查下标是否合法,当下标 >= size() 可能会出现段错误,
向量不会随着访问而扩容,而是通过添加元素才扩容
常用的成员函数
#include <vector>
void assign( size_type num, const TYPE& val );
功能:使用一组值为val的数据给向量赋值
void assign( input_iterator start, input_iterator end );
功能:使用一组范围[start,end)的数据给向量赋值
注意:赋值函数让向量原数据被覆盖,且数量会自动增加或者减少
#include <vector>
TYPE& at( size_type loc );
const TYPE& at( size_type loc ) const;
功能:访问下标为loc的元素,相当于[],当loc越界时at函数一定会抛异常,
但是[] 越界可能会段错误,脏数据,一切正常
#include <vector>
TYPE& back();
功能:返回向量中的最后一个元素
#include <vector>
TYPE& front();
功能:返回向量中的第一个元素
#include <vector>
iterator begin();
功能:返回指向第一个元素的迭代器
#include <vector>
iterator end();
功能:返回指向最后一个元素的下一个位置的迭代器
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
#include <vector>
size_type capacity() const;
功能:获取向量的容量,容量是可以随着向量的动态变化
#include <vector>
size_type size() const;
功能:获取向量的现有的元素数量
#include <vector>
void clear();
功能:清空向量中的所有元素,但是容量不变,数量清零
#include <vector>
bool empty() const;
功能:判断向量元素是否为空,空返回真
#include <vector>
iterator erase( iterator loc );
功能:删除一个元素
iterator erase( iterator start, iterator end );
功能:删除范围[start,end)的元素
注意:
1.参数必须提供迭代器
2.删除只是删除元素,容量不变
#include <vector>
iterator insert( iterator loc, const TYPE& val );
功能:在某个元素之前插入值为val的元素,位置必须以迭代器形式提供
void insert( iterator loc, size_type num, const TYPE& val );
功能:在某个元素之前插入 num 个值为val的元素,位置必须以迭代器形式提供
void insert( iterator loc, input_iterator start, input_iterator end );
功能:在某个元素之前插入一组[start,end)数组,位置必须以迭代器形式提供
#include <vector>
sizetype maxsize() const;
功能:计算向量最多能存储几个元素,该结果与向量存储的元素类型以及计算机的存储大小相关
#include <vector>
void pop_back();
功能:删除最后一个元素
#include <vector>
void push_back( const TYPE& val );
功能:在末尾添加一个元素,向量容量不足时,自动进行原容量翻倍的扩容
#include <vector>
reverse_iterator rbegin();
功能:返回一个逆向迭代器,它会指向最后一个元素
#include <vector>
reverse_iterator rend();
功能:返回一个逆向迭代器,它会指向第一个元素的前一个位置
#include <vector>
void reserve( size_type size );
功能:修改向量的容量
注意:只能修改为比原容量大
#include <vector>
void resize( size_type num, const TYPE& val = TYPE() );
功能:修改向量的元素个数
注意:
1.可以往大改,就会在末尾添加num个值为val的元素,且容量为num
2.可以往小改,相当于删除元素,容量不变
#include <vector>
void swap( container& from );
功能:交换两个向量的元素
list容器:
头文件: #include <list>
是一个功能齐全的双向链表
list( size_type num, const TYPE& val = TYPE() );
功能:创建num个元素,初始化为val的链表,不给默认为0;
list( input_iterator start, input_iterator end );
功能:使用一组数据初始化链表
所支持的运算符
= == !=
< > <= >=
也是链表整体以字符串比较规则进行比较
元素也支持 < 运算符才能使用以上运算符
常用的成员函数
#include <list>
void assign( size_type num, const TYPE& val );
功能:向链表中添加num个值为val数据
void assign( input_iterator start, input_iterator end );
功能:向链表添加一组数据
#include <list>
iterator begin();
功能:返回指向第一个元素的正向迭代器
const_iterator begin() const;
功能:返回指向最后一个元素的下一个位置的常正向迭代器
#include <list>
iterator end();
功能:返回指向最后一个元素的下一个位置的正向迭代器
const_iterator end() const;
功能:返回指向最后一个元素的下一个位置的常正向迭代器
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << endl;
}
#include <list>
TYPE& back();
功能:返回链表中的最后一个元素
#include <list>
TYPE& front();
功能:返回链表中的第一个元素
#include <list>
void clear();
功能:清空向量中的所有元素,但是容量不变,数量清零
#include <list>
iterator erase( iterator loc );
功能:删除链表中指定位置的元素,以迭代器形式提供位置
iterator erase( iterator start, iterator end );
功能:删除链表中[start,end)的元素,以迭代器形式提供位置
注意:链表的迭代器不允许使用 it + n ,it += n 这种语法,因为不支持随机访问
#include <list>
iterator insert( iterator loc, const TYPE& val );
功能:向链表中指定位置,插入一个值为val的元素,位置以迭代器形式提供
void insert( iterator loc, size_type num, const TYPE& val );
功能:向链表中指定位置,插入num个值为val的元素,位置以迭代器形式提供
template<TYPE> void insert( iterator loc, input_iterator start,
input_iterator end );
功能:向链表中指定位置,插入一组元素,位置以迭代器形式提供
#include <list>
void merge( list &lst );
功能:按照顺序合并两个链表,合并后lst的元素会删除
void merge( list &lst, BinPred compfunction );
#include <list>
void sort();
void sort( BinPred p );
功能:对链表元素进行快速排序,需要支持 < 运算符才行,否则,需要提供比较函数
注意:想要合并后有序,合并前也必须各自有序,需要先各自排序后合并,
注意:链表中的数据支持 < 运算符才能排序
#include <list>
reverse_iterator rbegin();
功能:返回一个逆向迭代器,它会指向最后一个元素
#include <list>
reverse_iterator rend();
功能:返回一个逆向迭代器,它会指向第一个元素的前一个位置
#include <list>
void remove( const TYPE &val );
功能:删除链表中所有等于val的值
#include <list>
void remove_if( UnPred pr );
功能:删除符合条件的元素
bool pr(const int& num)
{
return num < 50;//条件满足返回真,则会被删除
}
#include <list>
void resize( size_type num, const TYPE& val = TYPE() );
功能:修改链表中的元素数量为num
可以往大改,相当于尾增加值为val的元素
可以往小改,相当于尾删除
#include <list>
void reverse();
功能:反转链表
#include <list>
void splice( iterator pos, list& lst );
功能:把链表lst合并到当前链表的指定位置中,位置以迭代器形式提供,lst会删除所有元素
void splice( iterator pos, list& lst, iterator del );
功能:把链表lst指定del位置的元素合并到当前链表的指定pos位置中,
位置以迭代器形式提供,lst会删除del位置开始的元素
void splice( iterator pos, list& lst, iterator start, iterator end );
功能:把链表lst指定[start,end)位置的元素合并到当前链表的指定pos位置中,
位置以迭代器形式提供,lst会删除[start,end)位置的元素
#include <list>
void unique();
功能:删除重复元素,只保留一个
void unique( BinPred pr );
功能:删除重复元素,只保留一个;但元素类型必须支持 == 运算符,
否则需要提供比较函数 pr
queue 队列容器
头文件 #include <queue>
链式队列
不支持运算符、没有迭代器。只有无参构造和拷贝构造
#include <queue>
queue();
queue( const Container& con );
back 获取队尾元素
front 获取队头元素
empty 判断是否队空
push 入队
pop 出队
size 获取队列元素
stack 栈容器
头文件 #include <stack>
链式栈
不支持运算符、没有迭代器。只有无参构造和拷贝构造
push 入栈
pop 出栈
top 获取栈顶元素
size 获取栈元素数量
empty 判断是否栈空
Priority Queue 优先队列容器
头文件 #include <queue>
优先队列,该队列会对入队的数据进行排列,默认元素值越大,
优先级越高,越先出队
注意:存储元素必须支持 < 运算符
如果类型不支持,需要手动实现 < 运算符函数,可以根据需要在该函数中修改优先级
#include <queue>
priority_queue( const Compare& cmp = Compare(), const Container& c =
Container() );
priority_queue( input_iterator start, input_iterator end, const
Compare& comp = Compare(), const Container& c = Container() );
top 获取队头元素
empty 判断是否队空
push 入队
pop 出队
size 获取队列元素
deque 双向队列容器
头文件 #include <deque>
使用方式和向量容器一致,只是底层采用双向链表存储数据,而vector 是顺序表,
比vector节约内存,但是查找速度慢
支持运算符:
[] 可以向向量容器一样 “随机访问”
= == != < > <= >= 比较规则与vector一致
注意:虽然可以像随机访问一样去访问元素,但是底层是不支持随机访问的,
本质上[]运算符还是遍历访问,因此速度比vector慢,其实就是在vector
的基础上增加了双端操作
set容器 集合容器
头文件 #include <set>
集合容器,特点是元素不重复,会对元素自动排序,因此它存储的元素必须支持 < 运算符
只能使用迭代器遍历访问
底层:采用红黑树实现的
构造函数:
只能无参构造和拷贝构造
运算符:
与list一致
成员函数:
#include <set>
size_type count( const key_type& key );
功能:获取集合中key元素的数量,在set中只有1或0,意义不大
#include <set>
pair<iterator, iterator> equal_range( const key_type& key );
功能:查找set容器中值为key的元素位置范围,返回一个数据对[start迭代器,end迭代器)
因为set数据不重复,该函数意义不大
#include <set>
iterator find( const key_type& key );
功能:查找set中值为key的元素位置,如果找到返回该元素的迭代器,否则返回end()迭代器
#include <set>
iterator insert( iterator i, const TYPE& val );
void insert( input_iterator start, input_iterator end );
pair<iterator,bool> insert( const TYPE& val );
功能:向容器中插入一个数据
返回一个键值对,成功(first,true),否则(end,false)
#include <set>
key_compare key_comp() const;
功能:返回容器中元素的比较方法,使用该方法可以对该类型的数据进行比较
set<T> set;
set<T>::key_compare cmp = s.key_comp();
cout << cmp(1,4) << endl;
#include <set>
iterator lower_bound( const key_type& key );
功能:返回一个最小的大于等于key的元素迭代器
#include <set>
iterator upper_bound( const key_type& key );
功能:返回一个最小的大于key的元素迭代器
Multisets
头文件 #include <set>
多集合容器,特点是元素重复,会对元素自动排序,因此它存储的元素必须支持 < 运算符
只能使用迭代器遍历访问
底层是红黑树
#include <set>
pair<iterator, iterator> equal_range( const key_type& key );
功能:查找multiset容器中值为key元素位置范围,返回一个数据对[start迭代器,end迭代器)
map容器
头文件: #include <map>
映射容器 是由 (key/value)组成的元素(字典、键值对),要求键值对中的key不能重复,
而且会根据key进行排序,要求key类型必须支持 < 运算符
key和value是一一对应的,可以根据key来访问value
一般会在里面存储频繁需要查找的数据,因为map的查找速度特别快
(redis内存数据库)
底层采用红黑树存储,查找效率极高
#include <map>
map( iterator start, iterator end );
功能:使用一组pair<key/value>数据构造映射容器
map( iterator start, iterator end, const key_compare& cmp );
功能:使用一组pair<key/value>数据构造映射容器,并提供key的比较函数
支持[]运算符:
[] 通过使用key作为下标
既可以访问key的键值对,也可以给该键值对赋值(插入)
m[key] = value
#include <map>
iterator insert( iterator i, const TYPE& pair );
功能:在指定位置插入一个键值对(pair类型)
void insert( input_iterator start, input_iterator end );
功能:向映射容器插入一组数据(pair类型)
pair<iterator,bool> insert( const TYPE& pair );
功能:向映射容器插入一个键值对,返回插入的位置以及结果
#include <map>
key_compare key_comp() const;
功能:返回map容器中key的比较函数,该函数可以针对相同类型的键值对进行key的比较
#include <map>
value_compare value_comp() const;
功能:返回map容器中value的比较函数,该函数可以针对相同类型的键值对进行value的比较
multimap
头文件 #include <map>
多重映射容器
使用方法与map一致,但是不同的是它的key,可以对应多个value
所有它无法支持[]运算符
通过迭代器删除元素时需要注意的问题:
对于关联容器(set\multiset\map\multimap),删除当前iterator时,
仅仅会让当前迭代器失效,可以在erase时,递增当前的iterator可以连续删除 set.erase(it++),
因为它们底层都是红黑树,因此,插入、删除一个节点不会导致其他节点无法访问
对于顺序容器(vector),当删除当前的iterator会使后面的iterator失效,因为它底层是连续分配的内存
因此不能vector.erase(it++)
可以通过返回值拿下一个元素的迭代器,出现赋值给it即可
bitset容器
#include <bitset>
位集合容器,是一种封装了各种位运算符操作的数据结构
支持的运算符:
!= == &= ^= |= ~ <<= >>= []
成员函数
bool any();
功能:有任意一位二进制位1,返回真
size_type count();
功能:返回二进制位为1的位数
bitset<N>& flip();
bitset<N>& flip( size_t pos );
功能:指定二进制求反
bitset<N>& reset();
功能:把所有二进制置零
bitset<N>& reset( size_t pos );
功能:把指定二进制置零
bitset<N>& set();
功能:把所有二进制置1
bitset<N>& set( size_t pos, int val=1 );
功能:把指定二进制置1
size_t size();
功能:计算二进制的位数
bool test( size_t pos );
功能:测试某个二进制是0是1
string to_string();
功能:把二进制转换为字符串
unsigned long to_ulong();
功能:把二进制转换为 unsigned long
注意:bitset在C++中用处不大,但是在嵌入式开发中比较有用
为什么STL中很多容器底层采用红黑树