这里转载一篇写的更具体的文章:https://www.cnblogs.com/deng-tao/p/6020369.html
STL_容器
STL容器允许重复利用已有的实现构造自己特定类型下的数据结构,通过设置一些模板类,这些模板的参数允许用户指定容器中元素的数据类型,从而可以提高编程效率。
容器部分主要由头文件< deque>,< vector>,< list>,< map>,< queue>,< set>,< stack>组成。下表为常用的容器和容器适配器与头文件对应的关系。(stack和queue为容器适配器)
数据结构 | 描述 | 实现头文件 |
---|---|---|
向量(vector) | 连续存放的元素 | < vector > |
列表(list) | 由节点组成的双向链表,每个节点包含一个元素 | < list > |
双队列(deque) | 连续存储的指向不同元素的指针所组成的数组 | < deque > |
集合(set) | 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 | < set > |
栈(stack) | 后进先出的值的排列 | < stack > |
队列(queue) | 先进先出的值的排列 | < queue > |
映射(map) | 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 | < map > |
- 向量
向量是一种vector容器类,向量就像是盛放变长数组的容器,大约所有STL容器中有一半是基于向量的。vector是一种动态数组,是基本数组的类模板,其内部定义了很多基本操作。vector类中定义了四种构造函数:
(1).默认构造函数:其构造了一个初始长度为0的向量,其调用方式如下:
vector< int> v1;
(2).带有单个整型参数的构造函数:此参数描述了向量的初始大小,该构造函数还有一个可选的参数,这是一个类型为T的实例,描述了各个向量中各成员的初始值,其调用方式如下:
vector< int> v2(init_size,0);
(3).复制构造函数:构造一个新的向量,作为已存在的向量的完全复制,其调用方式如下:
vector< int> v3(v2);
(4).含有两个常量参数的构造函数:产生初始值为一个区间的向量。区间由一个半开区间[first,last)来指定,其调用方式如下:
vector< int> v4(first,last);
此外,在实际程序中使用较多的还是向量类的成员函数,其常用的成员函数包括:begin(),end(),push_back(),insert(),assign(),front(),back(),erase(),empty(),at(),size()。 - 列表
列表也是容器类的一种,其控制的长度为N的序列是以一个有着N个节点的双向链表来存储的,支持双向迭代器。使用列表的有时是可以在链表中插入和删除的元素或者子链表,只需改变前后指针就可以实现。
列表类的的定义如下:
typedef list< T,allocator< T>> mycont; //使用默认模板参数,可以省略第二个参数
例如,下列语句定义了两个list容器:
class TMyClass;
typedef list< TMyClass> TMyClassList; //用于存放对象的list容器
typedef list < TMyClass*> TMyClassPtrList; //用于存放对象指针的list容器
列表类其成员函数及作用如下所示:
resize:被控序列的长度改为只容纳n个元素,超出元素被删除。
clear:删除所有元素。
front,back:存取被控序列的第一个元素;存取被控序列的最后一个元素。
push_back:向对象末端插入值为x的元素。push_front为对象开始处插入元素,pop_back为删除最后一个元素,pop_front为删除第一个元素。
assign:为了将被控序列替换成由(first,last)所指定的序列。
insert:为了在迭代器it指定的元素前插入一个元素。
erase:删除it所指定的元素。
splice:将一系列的列表节点接入到一个列表中。
remove:删除所有值等于v的元素。
sort:将序列排序。
merge:将两个有序排序序列合并。
reverse:翻转整个序列。 - 集合
集合也是容器的一种,它的特点是集合中的元素的值是唯一的。在集合中,所有的成员都是排列好的。如果先后往一个集合插入:23,12,0,42,123,则输出该集合时为:0,12,23,42,123. - 双端队列
双端队列是一个queue容器类(队列容器),于vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据,因为其包含在开始端插入数据的函数push_front()。 - 栈
容器栈是一种特殊的容器,其特征是先进后出。栈容器支持的操作有如下五种:
empty:如果栈为空,返回true;否则返回false。
size:返回栈中元素的个数。
pop:删除,但不返回栈顶元素。
top:返回,但不删除栈顶元素。
push:放入新的栈顶元素。 - 映射
映射用于对数据进行快速和高效的检索。
容器使用简单实例
使用向量,将字符串传送到字符向量中并显示。
#include <iostream>
#include <vector>
using namespace std;
char* s="Hello world";
int main()
{
vector<char> vec; //用vector类模板定义了实例化对象vec,并使T具体化为char类型
vector<char>::iterator vi; //vector<char>::使iterator合法使用,定义了游标vi
char* p=s;
while(*p!='\0')
{
vec.push_back(*p); //push_back:向对象末端插入值为x的元素
p++; //指针++,直到字符串插入完毕
}
for(vi=vec.begin();vi<=vec.end();vi++)//begin()获取向量起始元素的游标
{
cout<<*vi;
}
return 0;
}
//运行结果:Hello world
具体一点的总结描述如下:(摘自原文:https://blog.csdn.net/huixieqingchu /article/details/79368351 )
a. vector容器是动态数组,在堆中分配内存,元素连续存放,有保留内存。若减少大小后内存也不会释放,当元素个数大于当前容量时,会分配原来2倍容量,从而将元素复制到新空间,原空间释放。可以快速随机访问元素,快速在末尾插入删除元素,此过程中不用移动内存;对中间元素插入删除时要移动内存。若元素是结构体类型或类,移动内存时还要进行构造和析构操作。vector可以使用[]操作符。
b. deque是双端队列,可以快速地随机访问元素,快速地在开始和末尾插入删除元素。随机插入比两端插入要慢,重新分配内存比vector要快。重新分配空间后,原空间保持,只是新建立了一个内存块,将新数据插入这个内存块,没有空间的复制删除过程,故deque是由多个分段连续的内存空间组成。因此,deque在某一位置上的操作是线性的,各小片内存间用链表相连,还是可以使用[],只是没有vector快。对deque排序,可以将其复制到vector中排完序后再复制回去。
c. list是一种双线性列表,只能顺序访问,不支持随机访问。对每个元素分配空间,不存在空间不够和重新分配的情况。
d. set是集合,支持快速查找,不允许有重复值,用平衡树结构来存储;multiset支持快速查找,允许有重复值。
e. map是映射,一对一映射,支持关键字快速查找,不允许有重复值;multimap是一对多映射,基于关键字查找,允许有重复值。