STL简介

STL(Standard Template Library),即标准模板库。该库提供了常用的数据结构和算法。

STL三种基本组件:

1、容器(container):容器是容纳、包含一组元素的对象。容器类库包括7种基本容器:向量(vector)、双端队列(deque)、列表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。其中容器又分为顺序容器和关联容器。

顺序容器:将一组具有相同的类型的元素已严格的线性形式组织起来(vector、deque、list)。

关联容器:具有根据一组索引来快速提取元素的能力(set、,multiset、map、multimsp)。

2、迭代器(iterator)迭代器提供了访问容器种每个元素的方法。对迭代器可以使用“++”运算符来获得指向下一个元素的迭代器,可以使用“*”运算符访问一个迭代器所指向的元素,也可以使用“->”运算符来访问类的成员,和指针的使用比较相似。指针本身也是一种迭代器,迭代器就是泛化的指针。

3、算法(algorithm):STL种包含七十多种算法,包括查找、排序、消除、计数等算法。

除了上面的三种基本组件,STL还包括三个辅助组件。

1、函数对象(function object):函数对象又被称为“仿函数”,可以像使用函数那样去使用它。重载“()”运算符的类的对象都可以被当作函数对象使用,函数对象是泛化的函数。用来扩展算法。

2、适配器(adapter):用于为已有对象提供新的接口的对象,适配器本身一般并不提供新的功能,只是为了改变对象的接口而存在的。

3、分配器(allocator):负责空间的配置和管理。

一、STL容器的底层实现和适用的场景

目录

一、STL容器的底层实现和适用的场景

(1)vector(向量)

(2)list(链表)

(3)deque(双向队列)

(4)set                                                                                                         (集合)和 multiset(多重集合)

(5)map(映射)和multimap(多重映射)

(6)hash_set(哈希集合)和hash_multiset(哈希多重集合)

(7)hash_map(哈希映射)和hash_multimap(哈希多重映射)

二、适配器(adapTTTTTTTTTTTTTTTTT    TTTTTTTTT         T                        ter)

1、容器适配器

三、分配器(allocaotr)


(1)vector(向量)

vector的底层实现为数组,和一般的数组不同的是,一般的数组在需要在定义时指定的数组的大小,一旦定义好之后数组的大小就不能发生改变,所以需要程序员在定义时,就确定数组的大小。而vector的大小是动态的,即可以在适用时自动扩容(只能增大,不能减少,即一旦容量升上去,就不会在降下来。)因为vector的底层是数组实现的,所以要求内存必须连续。但内存分配时,并不是在原数组的地址上向后扩容,而是会重新选择一块空间,将原来的数组拷贝过来(原因是:该数组原来地址的后面不一定有足够的空间)。所以vector在扩容上就比较浪费时间,所以在使用vector时,最好先指定数组的大小,以避免频繁的扩容浪费时间。在删除容器中元素时,和普通的数组的处理方式相同,将从该元素后面的元素全部向前移动一个位置,所以如果vector的元素类型时类时,就会导致对象的构造和析构,就会浪费大量的时间。所以当需要使用vector存储类时,一般建议使用对象的指针。

总结:适用于数据的频繁数据随机访问,且不需要频繁的插入和删除。

(2)list(链表)

list的底层实现为双向链表,和普通的链表相同,即插入和删除的时间复杂度都是O(1),但不支持数据元素的随机访问。

总结:适用于数据的频繁插入和删除,且不需要频繁的随机访问。

(3)deque(双向队列)

deque是一种双向开口(先入先出,即:头删尾插)的连续性空间。所谓的连续性,不过时让用户感觉为连续的,实际上是不连续的。duque的底层采用了“中央控制器”和缓冲区的结合方式,对外造成了整体连续的假象。“中央控制器”实际上就是使用了map。map占用一小段连续的空间,其中每个元素都是一个指针,用来记录每个缓冲区的地址,而且缓冲区的大小是固定的,默认为512b。所以每一块中存储的元素个数是相同的。

deque支持[]运算符,支持数据随机访问,在队尾插入和队头删除的效率都是O(1)。

总结:适用于需要随机存取,而且两端的数据需要插入和删除。

(4)set(集合)和 multiset(多重集合)

set的底层的数据结构是采用insert_unique方式插入红黑树(自平衡二叉查找树)

set总结:适用于去除数据中重复的元素的情况。

multiset的底层数据结构是采用insert_equal方式插入的红黑树。

(5)map(映射)和multimap(多重映射)

map的底层数据结构和set相同使用的是insert_unique方式插入红黑树,和set不同map的元素是键值对,键值对由键值(key)和实值(value)构成的,set的元素的只有一个实值。

map的用法很多:容器内元素频繁的查找,且数据的下标不一定是整形的情况。

这里需要注意的map和set内部的采用的结构是红黑树,所以会对加入容器的数据自动排序。

(6)hash_set(哈希集合)和hash_multiset(哈希多重集合)

hash_set和hash_multiset的底层实现是哈希表,由于哈希表是通过散列函数对数据进行分配空间的,所以在数据的查找上的速度为常数级。它和set和multiset的区别是它对 存入容器的数据不排序。

(7)hash_map(哈希映射)和hash_multimap(哈希多重映射)

hash_map和hash_multimap的底层实现是哈希表,它和map和multimap的区别也是对容器中的数据不排序。

这里需要注意一点:现在的c++11规定无序容器的同一命名规则为unordered_xx,所以hash_set,hash_multimap,hash_map和hash_multimap在现在c++11中的名称为:unordered_set,unordered_multiset,unordered_map和unordered_multimap。

二、适配器(adapter)

适配器的底层并没有具体数据结构实现,而是对其他STL的组件进行的一定的修改和封装。适配器的优点就在于可以让程序员选择最合适的容器来使用。

适配器分为三类:1、容器适配器 2、迭代器适配器 3、仿函数适配器

1、容器适配器

(1)stack(栈,默认基于deque(双向队列)实现)

(2)queue(队,默认基于deque(双向队列)实现)

(3)priority_queue(优先队列,默认基于vector(向量)实现)

三、分配器(allocaotr)

负责空间配置与管理。从实现的角度来看,配置器是一个实现动态空间配置、空间管理、空间释放的模板类。

STL分配器将内存管理中的分配和释放分开,其中内存分配交给alloc::allocate()负责,内存释放由alloc::dealloccate()负责;对像的构造由::construct()负责,对象的析构::destroy()负责。

同时为了提高内存管理的效率,减少申请内存造成的内存碎片问题,STL采用了两级配置器,当分配的内存大于等于128kb时,会使用第一级的空间配置器,在第一级空间适配器中内存是利用malloc()、realloc(),free()函数进行分配和释放的。当空间小于128k时,采用第二级空间配置器,第二级空间配置器采用了内存池技术,通过空闲链表来管理内存。
 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值