STL 学习笔记

代码路径:http://www.sgi.com/tech/stl/download.html


1, list 类

list内部为一个双向链表。用一个节点A表示结束节点。结束节点无有意义数据,用来标示链表结束。此节点的next为链表开始节点(第一个有效数据节点)。链表的最后一个有效数据节点的next为A。

iterator 的本质是一个Node指针,++时返回next, --时返回previous

size()操作比较费时,需要遍历整个链表。

2, vector 类

内部为一动态数租, iterator的本质是一个指针。erase,insert 操作将会移动后边所有元素。内存不够时,会重新分配两倍内存。默认构造函数数组长度为0,第一次分配为1.

3,deque类

内部一个动数组的数组。第一维度的数组存储一个_M_map的指针,_M_map是一个一维数组,在_M_map中存储实际的数据。这样当存储空间扩充时,仅仅需要重新拷贝第一维度,第二维度的数据不需要变化。而且两端都可以独立的扩充和缩减。

template <class _Tp, class _Alloc>
class _Deque_base {
......
protected:
  _Tp** _M_map;
  size_t _M_map_size;  
  iterator _M_start;
  iterator _M_finish;

......
};

与vector类对比,deque需要更多的管理代码,效率不如vector高。但是deque方便两端扩充,特别是当数据量比较大,而且变化更频繁时,deque可以减少更多的数据移动。

4,queue类

内部是一个deque,但是仅仅暴露出部分接口。queue没有迭代器。

5,string 类

string类的存储结构与vector相同,也是一维数组。默认构造函数会设定数组长度为8.

6,map 类

map类的内部为一红黑树,存取都为对数复杂度。当使用[]运算符时,如果元素key不存在,map类会插入一个元素默认值在key位置,并返回。map类的由begin()到end()的遍历是按照key的顺序遍历的。即二叉排序树的中序遍历。每个iterator实际上是一个二叉树的节点指针。

7,hash_map类

hash_map的本质上是一个hash_table类,核心的存储结构是一个vector,vector 存储的是链表的首地址。当hash后的key发生冲突时,会沿此链表依次存储。即采用拉链法解决hash地址冲突。 key元素对应的实际存储位置是hash(key)/vector.size()。当元素数量增长到一定程度时, 将对内部vector会进行扩容。扩容时会将vector中的每个元素按照新的size依次copy到一个临时的vector,最后将此vector swap回核心的存储vector。当删除元素时,内部的存储空间大小不会改变。所以hash_table的存储空间会一直增大直到析构。即使调用clear()也只会清除链表值,核心的vector大小不会回缩。当使用[]运算符时,如果元素key不存在,map类会插入一个元素默认值在key位置,并返回。hash_table的遍历是无序的。begin() 是vector中最左边一个非空节点。

8,set类

内部实现与map相同,为红黑树

9,hash_set 类

内部存储与hash_map相同,为哈希表


10, 内存分配 allocate

1)stl 将new操作的 ::new operator 和constructor 分开实现 (以及 ::delete和deconstructor)以提高效率。例如新建一个指定长度的vector时,只调用malloc 分配内存。当调用push_back时,才调用constructor

2)stl 中调用析构函数时会进行类型判断。如果是基本数据类型(int,char,double, int*.....)则跳过析构调用。

3)stl 中分配内存时采用分级处理,当要求分配内存小于128byte时,使用内存池,当大于128B时,直接调用malloc。用来防止内存碎片。








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值