转载 C++ STL 几个容器的底层实现

C++ STL 的实现:
 
1.vector      底层数据结构为数组 ,支持快速随机访问
 
2.list            底层数据结构为双向链表,支持快速增删
 
3.deque       底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问
deque是一个双端队列(double-ended queue),也是在堆中保存内容的.它的保存形式以下:
[堆1] --> [堆2] -->[堆3] --> ...
每一个堆保存好几个元素,而后堆和堆之间有指针指向,看起来像是list和vector的结合品.
 
4.stack        底层通常用list或deque实现,封闭头部便可,不用vector的缘由应该是容量大小有限制,扩容耗时
 
5.queue     底层通常用list或deque实现,封闭头部便可,不用vector的缘由应该是容量大小有限制,扩容耗时
 
(stack和queue实际上是适配器,而不叫容器,由于是对容器的再封装)
 
6.priority_queue     的底层数据结构通常为vector为底层容器,堆heap为处理规则来管理底层容器实现
 
7.set                   底层数据结构为红黑树,有序,不重复
 
8.multiset         底层数据结构为红黑树,有序,可重复 
 
9.map                底层数据结构为红黑树,有序,不重复
 
10.multimap    底层数据结构为红黑树,有序,可重复
 
11.hash_set     底层数据结构为hash表,无序,不重复
 
12.hash_multiset 底层数据结构为hash表,无序,可重复 
 
13.hash_map    底层数据结构为hash表,无序,不重复
 
14.hash_multimap 底层数据结构为hash表,无序,可重复 
http://www.cnblogs.com/hustlijian/p/3611424.html
------------------------------------------------------------------------------------------------------------------------------------------

stl容器区别: vector list deque set map-底层实现

stl容器区别: vector list deque set map (转)html

在STL中基本容器有: vector、list、deque、set、map前端

set 和map都是无序的保存元素,只能经过它提供的接口对里面的元素进行访问数组

set:集合, 用来判断某一个元素是否是在一个组里面,使用的比较少
map:映射,至关于字典,把一个值映射成另外一个值,若是想建立字典的话使用它好了
底层采用的是树型结构,多数使用平衡二叉树实现,查找某一值是常数时间,遍历起来效果也不错, 只是每次插入值的时候,会从新构成底层的平衡二叉树,效率有必定影响.数据结构

vector、list、deque是有序容器
1.vector
vector就是动态数组.它也是在堆中分配内存,元素连续存放,有保留内存,若是减小大小后,内存也不会释放.若是新值>当前大小时才会再分配内存.post

它拥有一段连续的内存空间,而且起始地址不变,所以它能很是好的支持随即存取,即[]操做符,但因为它的内存空间是连续的,因此在中间进行插入和删除会形成内存块的拷贝,另外,当该数组后的内存空间不够时,须要从新申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。

对最后元素操做最快(在后面添加删除最快 ), 此时通常不须要移动内存,只有保留内存不够时才须要性能

 

对中间和开始处进行添加删除元素操做须要移动内存,若是你的元素是结构或是类,那么移动的同时还会进行构造和析构操做,因此性能不高 (最好将结构或类的指针放入vector中,而不是结构或类自己,这样能够避免移动时的构造与析构)。
访问方面,对任何元素的访问都是O(1),也就是是常数的,因此vector经常使用来保存须要常常进行随机访问的内容,而且不须要常常对中间元素进行添加删除操做.测试

相比较能够看到vector的属性与string差很少,一样可使用capacity看当前保留的内存,使用swap来减小它使用的内存.url

capacity()返回vector所能容纳的元素数量(在不从新分配内存的状况下)      测试push_back  1000个数据  capacity返回16384

 

总结
须要常常随机访问请用vector.net

2.list
list就是双向链表,元素也是在堆中存放,每一个元素都是放在一块内存中,它的内存空间能够是不连续的,经过指针来进行数据的访问,这个特色使得它的随机存取变的很是没有效率,所以它没有提供[]操做符的重载。但因为链表的特色,它能够以很好的效率支持任意地方的删除和插入。指针

list没有空间预留习惯,因此每分配一个元素都会从内存中分配,每删除一个元素都会释放它占用的内存.

list在哪里添加删除元素性能都很高,不须要移动内存,固然也不须要对每一个元素都进行构造与析构了,因此经常使用来作随机操做容器.
可是访问list里面的元素时就开始和最后访问最快
访问其它元素都是O(n) ,因此若是须要常常随机访问的话,仍是使用其它的好

总结
若是你喜欢常常添加删除大对象的话,那么请使用list
要保存的对象不大,构造与析构操做不复杂,那么可使用vector代替
list<指针>彻底是性能最低的作法,这种状况下仍是使用vector<指针>好,由于指针没有构造与析构,也不占用很大内存

3.deque
deque是一个双端队列(double-ended queue),也是在堆中保存内容的.它的保存形式以下:
[堆1]
...
[堆2]
...
[堆3]
每一个堆保存好几个元素,而后堆和堆之间有指针指向,看起来像是list和vector的结合品.

它支持[]操做符,也就是支持随即存取,可让你在前面快速地添加删除元素,或是在后面快速地添加删除元素,而后还能够有比较高的随机访问速度,和vector的效率相差无几,它支持在两端的操做:push_back,push_front,pop_back,pop_front等,而且在两端操做上与list的效率也差很少。
在标准库中vector和deque提供几乎相同的接口,在结构上它们的区别主要在于这两种容器在组织内存上不同,deque是按页或块来分配存储器的,每页包含固定数目的元素.相反vector分配一段连续的内存,vector只是在序列的尾段插入元素时才有效率,而deque的分页组织方式即便在容器的前端也能够提供常数时间的insert和erase操做,并且在体积增加方面也比vector更具备效率

总结:
vector是能够快速地在最后添加删除元素,并能够快速地访问任意元素
list是能够快速地在全部地方添加删除元素,可是只能快速地访问最开始与最后的元素
deque在开始和最后添加元素都同样快,并提供了随机访问方法,像vector同样使用[]访问任意元素,可是随机访问速度比不上vector快,由于它要内部处理堆跳转
deque也有保留空间.另外,因为deque不要求连续空间,因此能够保存的元素比vector更大,这点也要注意一下.还有就是在前面和后面添加元素时都不须要移动其它块的元素,因此性能也很高。

所以在实际使用时,如何选择这三个容器中哪个,应根据你的须要而定,通常应遵循下面
的原则:
一、若是你须要高效的随即存取,而不在意插入和删除的效率,使用vector
二、若是你须要大量的插入和删除,而不关心随即存取,则应使用list
三、若是你须要随即存取,并且关心两端数据的插入和删除,则应使用deque。

原文出处http://hi.baidu.com/zhouhq_926/blog/item/b1ee859762cc426754fb9665.html

相关文章
相关标签/搜索