STL常用容器详细解析

 更新时间:2013年09月23日 09:33:39   作者:  
这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点STL中的常用容器包括:顺序性容器(vector、deque、list)、关联容器(map、set)、容器适配器(queue、stac)

STL是C/C++开发中一个非常重要的模板,而其中定义的各种容器也是非常方便我们大家使用。下面,我们就浅谈某些常用的容器。这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点。STL中的常用容器包括:顺序性容器(vector、deque、list)、关联容器(map、set)、容器适配器(queue、stac)。

1、顺序性容器

(1)vector
vector是一种动态数组,在内存中具有连续的存储空间,支持快速随机访问。由于具有连续的存储空间,所以在插入和删除操作方面,效率比较慢。vector有多个构造函数,默认的构造函数是构造一个初始长度为0的内存空间,且分配的内存空间是以2的倍数动态增长的,即内存空间增长是按照20,21,22,23.....增长的,在push_back的过程中,若发现分配的内存空间不足,则重新分配一段连续的内存空间,其大小是现在连续空间的2倍,再将原先空间中的元素复制到新的空间中,性能消耗比较大,尤其是当元素是非内部数据时(非内部数据往往构造及拷贝构造函数相当复杂)。vector的另一个常见的问题就是clear操作。clear函数只是把vector的size清为零,但vector中的元素在内存中并没有消除,所以在使用vector的过程中会发现内存消耗会越来越多,导致内存泄露,现在经常用的方法是swap函数来进行解决: 

vector<int> V;V.push_back(1); V.push_back(2);V.push_back(1); V.push_back(2);
vector<int>().swap(V); 或者 V.swap(vector<int>());

利用swap函数,和临时对象交换,使V对象的内存为临时对象的内存,而临时对象的内存为V对象的内存。交换以后,临时对象消失,释放内存。

(2)deque
deque和vector类似,支持快速随机访问。二者最大的区别在于,vector只能在末端插入数据,而deque支持双端插入数据。deque的内存空间分布是小片的连续,小片间用链表相连,实际上内部有一个map的指针。deque空间的重新分配要比vector快,重新分配空间后,原有的元素是不需要拷贝的。

(3)list
list是一个双向链表,因此它的内存空间是可以不连续的,通过指针来进行数据的访问,这使list的随机存储变得非常低效,因此list没有提供[]操作符的重载。但list可以很好地支持任意地方的插入和删除,只需移动相应的指针即可。

(4)在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:
    1) 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
    2) 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
    3) 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque

2、关联容器

(1)map
map是一种关联容器,该容器用唯一的关键字来映射相应的值,即具有key-value功能。map内部自建一棵红黑树(一种自平衡二叉树),这棵树具有数据自动排序的功能,所以在map内部所有的数据都是有序的,以二叉树的形式进行组织。这是map的模板:

template < class Key, class T, class Compare= less<Key>, class Allocator=allocator< pair<const Key,T> > > class map;

从模板中我们可以看出,再构造map时,是按照一定的顺序进行的。map的插入和删除效率比其他序列的容器高,因为对关联容器来说,不需要做内存的拷贝和移动,只是指针的移动。由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑色),所以map的其中的一个缺点就是比较占用内存空间。

(2)set
set也是一种关联性容器,它同map一样,底层使用红黑树实现,插入删除操作时仅仅移动指针即可,不涉及内存的移动和拷贝,所以效率比较高。set中的元素都是唯一的,而且默认情况下会对元素进行升序排列。所以在set中,不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,再插入新元素。不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取。set模板原型:

template <class Key, class Compare=class<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) > class set;
set支持集合的交(set_intersection)、差(set_difference)、并(set_union)及对称差(set_symmetric_difference) 等一些集合上的操作。

3、容器适配器

(1)queue
queue是一个队列,实现先进先出功能,queue不是标准的STL容器,却以标准的STL容器为基础。queue是在deque的基础上封装的。之所以选择deque而不选择vector是因为deque在删除元素的时候释放空间,同时在重新申请空间的时候无需拷贝所有元素。其模板为:
template < TYPENAME _Sequence="deque<_TP" typeneam _Tp,> > class queue;

(2)stack
stack是实现先进后出的功能,和queue一样,也是内部封装了deque,这也是为啥称为容器适配器的原因吧(纯属猜测)。自己不直接维护被控序列的模板类,而是它存储的容器对象来为它实现所有的功能。stack的源代码原理和实现方式均跟queue相同。

相关文章

  • C++实现LeetCode(188.买卖股票的最佳时间之四)

    C++实现LeetCode(188.买卖股票的最佳时间之四)

    这篇文章主要介绍了C++实现LeetCode(188.买卖股票的最佳时间之四),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++读取到回车换行符问题处理

    C++读取到回车换行符问题处理

    有一个程序只需对输入的一行字符一个个进行独立判断,C的话用getchar()就好了,但是用C++的时候发现CIN似乎不接受回车符……搜索解决方法的时候很多人都建议将getline,然后处理数组或者定义一个流什么的,但是这样一行可能很长,要占用很多空间。有没有别的办法?
    2015-08-08
  • C语言中进制知识汇总

    C语言中进制知识汇总

    在C语言里,整数有三种表示形式:十进制,八进制,十六进制。 其中以数字0开头,由0~7组成的数是八进制。以0X或0x开头,由0~9,A~F或a~f 组成是十六进制。除表示正负的符号外,以1~9开头,由0~9组成是十进制。
    2016-05-05
  • vscode 配置 C/C++ 编译环境的详细图文教程

    vscode 配置 C/C++ 编译环境的详细图文教程

    这篇文章主要介绍了vscode 配置 C/C++ 编译环境的详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • C++使用异或运算实现交换两个数的值

    C++使用异或运算实现交换两个数的值

    交换两个数的值,通常用利用一个变量来交换数值,异或交换两个数的值是资源开销最小的方法,不需要中介数,原理简单的来说就是异或的负负得正
    2018-09-09
  • 浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    下面小编就为大家带来一篇浅谈带缓冲I/O 和不带缓冲I/O的区别与联系。小编觉得挺不错的现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 安装OpenMPI来配合C语言程序进行并行计算

    安装OpenMPI来配合C语言程序进行并行计算

    这篇文章主要介绍了安装OpenMPI来配合C语言程序进行并行计算的例子,MPI的全称是Message Passing Interface即标准消息传递界面,可以用于并行计算,需要的朋友可以参考下
    2015-11-11
  • C/C++ 宏详细解析

    C/C++ 宏详细解析

    关于宏的一些语法问题,可以在google上找到。相信我,你对于宏的了解绝对没你想象的那么多。如果你还不知道#和##,也不知道prescan,那么你肯定对宏的了解不够
    2013-09-09
  • C++从文本文件读取数据到vector中的方法

    C++从文本文件读取数据到vector中的方法

    这篇文章主要给大家介绍了利用C++如何从文本文件读取数据到vector中,文章通过实例给出示例代码,相信会对大家的理解和学习很有帮助,有需要的朋友们下面来一起看看吧。
    2016-10-10
  • C++11显示类型转换的优点

    C++11显示类型转换的优点

    这篇文章主要介绍了C++11显示类型转换的优点,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08

最新评论