维基百科定义:

In computer science, a container is a class, a data structure,[1][2] or an abstractdata type (ADT) whose instances are collections of other objects. In other words;they are used for storing objects in an organized way following specific acce***ules.

图示:

wKioL1QAjIGAwAGSAACz9M2HB_s401.jpg

wKiom1QAi2mAS70tAACGfZst26o181.jpg

顺序性容器:


向量 vector   


是一个线性顺序结构。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。


双向链表list


是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有序的元素链接起来。


双端队列deque 
是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪。向deque 两端添加或删除元素的开销很小。它不需要重新分配空间,所以向末端增加元素比vector 更有效。


实际上,deque 是对vector list 优缺点的结合,它是处于两者之间的一种容器。


vector 、list 、deque 在内存结构上的特点

vector 是一段连续的内存块,而deque 是多个连续的内存块, list 是所有数据元素分开保存,可以是任何两个元素没有连续。

vector 的查询性能最好,并且在末端增加数据也很好,除非它重新申请内存段;适合高效地随机存储。

list 是一个链表,任何一个元素都可以是不连续的,但它都有两个指向上一元素和下一元素的指针。所以它对插入、删除元素性能是最好的,而查询性能非常差;适合大量地插入和删除操作而不关心随机存取的需求。

deque 是介于两者之间,它兼顾了数组和链表的优点,它是分块的链表和多个数组的联合。所以它有被list 好的查询性能,有被vector 好的插入、删除性能。如果你需要随即存取又关心两端数据的插入和删除,那么deque 是最佳之选。



关联容器:

set, multiset, map, multimap 是一种非线性的树结构,具体的说采用的是一种比较高效的特殊的平衡检索二叉树—— 红黑树结构。(至于什么是红黑树,我也不太理解,只能理解到它是一种二叉树结构)

因为关联容器的这四种容器类都使用同一原理,所以他们核心的算法是一致的,但是它们在应用上又有一些差别,先描述一下它们之间的差别。

set:又称集合,实际上就是一组元素的集合,但其中所包含的元素的值是唯一的,且是按一定顺序排列的,集合中的每个元素被称作集合中的实例。因为其内部是通过链表的方式来组织,所以在插入的时候比vector 快,但在查找和末尾添加上被vector 慢。

multiset:是多重集合,其实现方式和set 是相似的,只是它不要求集合中的元素是唯一的,也就是说集合中的同一个元素可以出现多次。

map :提供一种- 关系的一对一的数据存储能力。其在容器中不可重复,且按一定顺序排列(其实我们可以将set 也看成是一种键- 值关系的存储,只是它只有键没有值。它是map 的一种特殊形式)。由于其是按链表的方式存储,它也继承了链表的优缺点。

multimap :和map 的原理基本相似,它允许在容器中可以不唯一。


顺序容器示例:

//顺序容器list
#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> list_object;
    
    for(int i = 0;i <=5;i++)
        list_object.push_back(i);
        
    cout<<"List containers:\n";
    list<int>::iterator iter;
    
    for(iter = list_object.begin();iter != list_object.end();iter++)
        cout<<*iter<<" ";
        
    cout<<endl;
    cout<<"Setting all entries to 0:\n";
    for(iter = list_object.begin();iter != list_object.end();iter++)
        *iter = 0;
        
    cout<<"List now containers:\n";
    for(iter = list_object.begin();iter != list_object.end();iter++)
        cout<<*iter<<" ";
        
    cout<<endl;
    
    return 0;
    
}

结果:

List containers:
0 1 2 3 4 5 
Setting all entries to 0:
List now containers:
0 0 0 0 0 0