2.C++ STL之容器分类与测试

容器的分类

①序列(循序)容器

a.数组Array(无法扩充)
b.向量Vector(内存后面自动扩充)
c.双向队列Deque(前面和后面都可扩充)
d.双向链表List(源代码还是个环,前后都可扩充)
e.单向链表Forward-List
双向链表比单向链表耗用更多的内存,因为一个指针在32位电脑上占四个字节。

②关联式容器(适合于快速查找)

由关键字快速找值。
①Set/Multiset
内部用红黑树做的。红黑树是高度平衡二分树,能够调整左子树和右子树差不多,不会导致一边过长一边过短。
Key=Value红黑树
②Map/Multimap红黑树
Key->Value(对应)

③不定序容器(c++ 11新出的)

位置不固定,可能随时间改变。用Hash Table做的。
Unodered Set/Multiset:
在这里插入图片描述
Unordered Map/Multimap
在这里插入图片描述

附加:Hash Table
在这里插入图片描述
最好的做法是Separate Chaining
元素碰撞,就将其分开–>该做法是碰撞的元素放在同一个篮子里面,用链表链接起来,但不能过长,过长需要重新设置。

总结

  1. array、vector、deque的内存是连续的,连续的内存空间必定是支持随机访问的,其余容器则不具备该特点。其中array为固定长度,vector、deque为变长,其中vector每次增加原本大小的大小长度,vector只能单向扩充,deque可以双向扩充,每次增加一个buffer大小。vector和deque删除和插入时,后序元素会发生联动效应,因此也不适合做频发的删除和插入。
  2. list、forward-list为链条式结构,这种结构在插入、删除时只需要局部调整非常方便。但是遍历时只能按照链条顺序依次遍历,查找起来并不迅速,每次都增加一个结点。
  3. set、map背后的实现为红黑树,所以对查找具有先天的优势,但这种结构插入删除时会产生联动效应,所以并不适合做频发的删除、插入。其中各自multi版本表示内容可以重复。

测试

(一)容器array

1.随机向容器array中插入50000个元素。

array<long,ASIZE> c;//ASIZE=50000

2.对容器array中的50000个元素进行快速排序,并且二分查找法查找某个元素

qsort(c.data(),ASIZE,sizeof(long),compareLongs);//快速排序
long *pItem=(long*)bsearch(&target,(c.data()),ASIZE,sizeof(long),compareLongs);//二分查找法

3.得出排序的所需要的时间为187毫秒,即0.187秒
在这里插入图片描述

(二)容器vector

vector的空间增长以2的倍数增长,即由1->2->4->8->…->2n
如果不用,就会造成空间浪费。

vector.size();//返回元素的个数
vector.capacity();//返回空间的大小

当size=100,0000时,capacity=1048576
1.push_back()一百万个元素,花费3063毫秒,即3.063秒。
2.find(c.begin(),c.end(),target)
寻找一个元素,花费0毫秒。
3.

sort(c.begin(),c.end());
string *pItem=(string*)bsearch(&target,(c.data()),c.size(),sizeof(string));

花费2765毫秒,即2.765秒。

(三)容器list

双向链表
每次扩充一个结点,结点很小,效率最高,空间利用率最高,但是找起来很慢。
1.push_back() 100,0000个元素,所花时间为3265毫秒,即3.265秒
2.max_size()=3,5791,3941//??????????????
3.find(c.begin(),c.end(),target) 16毫秒
4.c.sort() 花费2312毫秒
标准库的sort()和容器的sort()
通常容器提供的sort()更快

(四)容器forward_list

单向链表,c++ 11标准新有
只有push_front() 因为只有一端,不提供另一端(太慢,就像vector)
不提供push_back(),back()
1.push_front() 100万个元素,花费3204毫秒
2.find(c.begin(),c.end(),target) 花费15毫秒
3.c.sort() 花费2656毫秒

(五)容器slist

非标准库,单向串链表,与forward_list一样,都是单向链表,用法、概念相同。
节点结构是采用继承的方式来进行组织的,而不是使用组合的方式来进行组织。
1.push_front() 100万个元素,花费3046毫秒

(六)容器deque

双向扩充,扩充时找到双倍大小的内存空间。
(buffer)分段连续,他是号称段与段之间是连续的,但这是假象,让使用者整个是连续的。
在这里插入图片描述
继续放元素时,分配另外一个buffer,另外一个指针指向这个buffer。
左右指针,指向左右的buffer。每次扩充一个buffer。
1.push_back() 100万元素 2704毫秒
2.max_size()=1073741823 所有容器种deque最大
3.find(c.begin(),c.end(),target) 花费15毫秒
4.::sort() 全局排序 因为deque没有自己的sort() 花费3110毫秒

关联式容器,查询特别快!
deque涵盖了stack和queue的功能,stack和queue没有实现什么数据结构,而是使用deque做底部支撑!
由于这两个容器没有自己的数据结构,所以技术上又把他们称为容器适配器。
而且不提供iterator,避免使用iterator删除修改前面的元素,因此也没有find函数,因为返回一个iterator。

(七)容器stack

先进后出。

(八)容器queue

先进先出。

(九)容器multiset

查找特别快,可以看成一个小型数据库。<使用红黑树>高度平衡树
没有push_back()和push_front()
只有insert,内部自动放在正确的位置。
1.insert() 100万个元素,时间花了6609毫秒,即6.609秒 需要排序,时间较长
2.max_size()=2,1474,8364
3.::find(c.begin(),c.end(),target) 全局函数 花费203毫秒
4.c.find(target) 容器内部函数,花费0毫秒,因为这个容器在插入时就排好序

(十)容器multimap

<使用红黑树>高度平衡树
没有push_back()和push_front()
只有insert,内部自动放在正确的位置。
c.insert(pair<type,type>(ct,ct));
不可以用下标!!因为有重复的key!
1.insert() 100万个元素,时间花了4812毫秒,即4.812秒 需要排序,时间较长
2.max_size()=1,7895,6970
3.c.find() 花费0毫秒

(十一)容器unordered_multiset

<使用hash table>
1.c.insert(type(ct)); 100万个元素,花费4406毫秒 即4.406秒
2.max_size()=357913941
3.c.bucket_count() 105,6323 篮子的个数>元素的个数,合理,有的篮子没有元素,有个篮子n个元素(n>1),而篮子一定比元素多,因为若是篮子比元素少,那么每个篮子的元素太多,循序查找,很慢(经验法则:若元素个数>篮子个数,扩充篮子的个数✖2,将原本的元素打散,重新放入篮子内)
4.load_factor() =0.94668 载重因子
5.::find() 花费109毫秒
6.c.find() 花费0毫秒

(十二)容器unordered_multimap

最适合搜寻大量元素

(十三)容器set

<使用红黑树>
key一定要时独一无二的!!不可以重复!
1.insert() 花费3922毫秒
2.size()=32768 随机放入100万个元素,符合概率(不可以重复)

(十四)容器map

<使用红黑树>
key一定要时独一无二的!!不可以重复!
1.c[key]=val;等同insert
2.size()=100,0000 随机放入100万个元素,value可以重复,key不可以重复

(十五)容器unordered_set

<使用hash table>

(十六)容器unordered_map

<使用hash table>

(十七)容器heap

使用其他容器做底部支撑,不算是真正的容器,算是容器适配器

结构

序列式容器
array(连续空间)
vector(连续空间)
-heap(以算法形式呈现 xxx_heap())
- -priority_queue
(可以说heap里头有一个vetcor,priority_queue里头有一个heap)

list(双向)
slist(单向)改名:forward_list
deque(分段连续空间)
-stack(容器适配器)
-queue(容器适配器)

关联式容器
rb_tree(非公开,红r黑b树)
-set
-map
-multiset
-multimap
hashtable(非公开)
-hash_set(非标准)unordered_set
-hash_map(非标准)unordered_map
-hash_multiset(非标准)unordered_multiset
-hash_multimap(非标准)unordered_multimap

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值