在介绍STL容器之前,我先来介绍一下命名空间(namespace)、<>和<.h>之间的区别等一些我个人认为比较让人模糊的东西!
命名空间(namespace):即名称的一个约束空间,对标识符的名称进行本地化操作,避免命名冲突。namespace使得我们可以通过创建作用范围来对全局命名空间进行分隔;声明方式:namespace 名称{ // 相关内容}
举个例子,std就是一个命名空间,旧标准的C++中使用#include<iostream.h>头文件,在新标准的C++中则使用#include<iostream>,两者的区别在于后者包含了std这样一个命名空间,即在使用#include<iostream>头文件时,要使用using namespace std;或者用std::string的形式使用命名空间std中定义的内容。如下的vector等都是定义在std中的。
1、vector
简单的说:vector是一个能够存放任意数据类型的动态数组,能够增减和压缩数据。
push_back(Type value):在尾部插入一个Type类型的数据;
pop_back():删除末尾的数据;
assign(begin, end):将begin和end区间的数据拷贝到一个容器;
assign(n,elem):往容器中放入n个elem元素;
at(nIndex):传回索引为nIndex的值,如果越界(nIndex大于等于容器长度)则抛出out_of_range异常;
begin():返回指向第一个数据的迭代器;
end():返回指向最后一个数据的迭代器;
capacity():返回容器中数据个数;
clear():移出容器中的所有数据;
empty():判断容器是否为空;
erase(iterator iter):删除iter所指向的元素,并返回下一个数据的iter;
erase(begin, end):删除begin和end区间的数据,并返回下一个数据的iter;
front():返回第一个数据;
back():返回最后一个数据,不检查这个数据是否存在;
insert(pos, elem):在pos位置插入一个elem的拷贝,返回插入值的迭代器;
insert(pos, n, elem):在pos位置插入n个elem的数据,无返回值;
size():返回容器中实际数据的个数;
swap():交换两个类型一样的容器;
shrink_to_fit():实现vector的压缩;//根据容器中元素的实际个数,即size();重新计算capacity();
2、map
键值和映照数据之间可以建立一个数学上的映照关系,map的实现原理是基于RBTree,对于红黑树,我不了解,想了解的可以网上查资料;
map<Type key, Type value>:map容器的一般定义方式;
插入元素:
insert(pair<Type,Type>(key,value)):一般的插入元素方式;
insert(map<Type,Type>::type_value(key,value));
还可以通过数组的方式直接插入:mapList[key] = value;
删除元素:
erase(iterator pos):删除迭代器pos所指位置元素;
erase(const key_type& k):删除指定键值对应的元素;
erase(iterator first, iterator last):删除迭代区间上所有元素;
clear():删除map容器的所有元素;
empty():map容器是否为空;
size():容器中元素个数;
遍历元素:
除了利用键值的数组方式来访问元素外,更一般可使用 map 容器的迭代器进行访问,通常需要用 begin 和 end 函数找出遍历开始的首元素和结束元素,然后通过迭代器的“++” 和“*” 操作,读取容器元素;
map容器提供的find函数,可搜索出具有某一键值的元素:若成功返回元素对应迭代器,不成功则返回一个end结束位置;
3、List
实际上list容器就是一个双向链表,可以高效的进行插入删除元素;
构造函数:
list<Type> lc;
list<Type> lc(3);
list<Type> lc(5,2)
list<Type> lc(lcV)
成员函数:
begin():返回指向链表第一个元素的迭代器
end():返回指向链表最后一个元素的迭代器
rbegin():返回逆向链表的第一个元素,也就是链表的最后一个元素
rend():返回逆向链表的最后一个元素,也就是链表的第一个数据再往前的位置
assign(n, num):将n个num拷贝赋值给链表
front():返回链表的第一个元素
back():返回链表的最后一个元素
empty():判断链表是否为空
size():返回链表实际元素的个数
max_size():返回链表所能容纳的最大元素的数量
clear():清空链表所有元素
insert(pos, num):在pos位置插入元素num
insert(pos, n, num):在pos位置上插入n个num元素
insert(pos, begin, end):在pos位置上插入一个列表的始末位置元素
erase(pos):删除pos位置的元素
remove(num):删除链表中匹配的num元素
remove_if(_cmp):删除满足条件的元素,参数为自定义回调函数
push_back(num):在链表末尾增减一个元素
pop_back():删除链表末尾元素
push_front():在链表开始位置增加一个元素
pop_back():删除第一个元素
swap():交换两个链表内容
reverse():反转链表
sort():对链表排序,默认升序
sort(_cmp):自定义回调函数实现自定义排序
4、queue
queue是一个单向队列,也是以别的容器作为底部结构的,只是给出接口使之符合单向队列的特性。
queue<Type> ql:创建一个单向队列
queue<Type> ql(QL):用一个单向队列去创建另一个队列
front():返回队列头部数据
back():返回队列尾部数据
push(elem):在队尾增减elem数据
pop():队列头部数据出队
empty():判断队列是否为空
size():返回队列中实际元素个数
5、stack
堆栈的底层使用的是其他容器,因此堆栈可以被看做是一种适配器,即将一种容器转换为另一种容器;stack严格最受先进后出原则,故stack不提供元素的任何迭代器操作。
stack():默认构造函数,创建一个空的stack对象
stack(const stack&):复制构造函数,用一个stack堆栈创建一个新的堆栈
void push(const value_type& x):入栈不考虑栈满情况
void pop():出栈前需自己判断栈是否为空
empty():判断栈是否为空
value_type& top():取出最后入栈的元素,即栈顶元素
size():返回当前堆栈的元素个数
stack的元素出栈操作是不返回栈顶元素的,需要另外通过取栈顶函数获得。这种分离实现是考虑到出栈函数若直接返回栈顶元素,将会导致返回值的数据引用安全问题或不必要的低效复制函数的调用。
6、deque
deque与vector类似,支持随机访问和快速插入删除,在容器的某位置上的操作所花时间是线性的,deque与vector不同的是支持从开始端插入数据:push_front();
deque<Type> dq:创建一个空的deque
deque<Type> dq(DQ):用一个DQ队列去创建一个新的deque
deque<Elem> c(n) 创建一个deque,含有n个数据,数据均已缺省构造产生。
deque<Elem> c(n, elem) 创建一个含有n个elem拷贝的deque。
deque<Elem> c(beg,end) 创建一个以[beg;end)区间的deque。
begin():返回指向第一个元素的迭代器
end():返回指向最后一个元素的迭代器
rbegin():返回最后一个元素的迭代器
rend():返回第一个元素的迭代器
c.assign(n,num)将n个num拷贝复制到容器c
c.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器c
empty():判断deque是否为空
at(pos):获取索引pos位置上的元素,会执行边界检查,如果越界则跑出异常
front():返回第一个元素
back():返回最后一个元素
size():deque所拥有的实际元素个数
clear():清除所拥有的所有元素
c.insert(pos,num)在pos位置插入元素num
c.insert(pos,n,num)在pos位置插入n个元素num
c.insert(pos,beg,end)在pos位置插入区间为[beg,end)的元素
c.erase(pos)删除pos位置的元素
c.erase(beg,end)删除区间为[beg,end)之间的元素
c.push_back(num)在末尾位置插入元素
c.pop_back()删除末尾位置的元素
c.push_front(num)在开头位置插入元素
c.pop_front()删除开头位置的元素
c1.swap(c2)交换容器c1,c2; 同理:swap(c1,c2)也可以交换