stl源码剖析_《STL源码剖析》学习笔记

第二章 空间配置器

stl源码剖析_《STL源码剖析》学习笔记_第1张图片

stl源码剖析_《STL源码剖析》学习笔记_第2张图片

stl源码剖析_《STL源码剖析》学习笔记_第3张图片

stl源码剖析_《STL源码剖析》学习笔记_第4张图片

stl源码剖析_《STL源码剖析》学习笔记_第5张图片

简述空间配置器:

关于一级空间配置器:

直接使用malloc、free、realloc进行内存管理操作。且在内存不足时,会陷入oom_malloc,即模拟C++的set_new_handler。但没有new_handler,则抛出bad_alloc;

关于二级空间配置器:(避免太多小额区块照成内存碎片)

  1. 对于大于128bytes的,直接使用malloc和free;
  2. 对于小于128bytes的内存申请,使用16个空闲链表维护,每个链表相差8bytes。

a. 对于申请的内存会up到8的整数倍的大小size,再去据此查找合适的空闲链表。

b. 如果该空闲链表足够,则直接分配;

c. 否则,向内存池申请20个这样的size,如果内存池足够,则返回;

d. 否则,内存池如果有这样的size,则尽可能多的返回;

e. 否则,将内存池的剩余的空间赋予对应的空闲链表,并malloc申请40个这样的size的内存;

f. 如果申请成功,则进行正常返回(留20个在内存池);

g. 如果申请失败,则调用一级空间配置器(其由oom的机制),分配40个这样的size的内存;

h. 如果一级空间配置器成功,则一切ok;否则,会触发bad_alloc;

第三章 迭代器概念与traits编程技法

1)Iterator模式定义如下:提供一种方法使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达式;

2)所谓partial specialization的意思是提供另一份template定义式,而其本身仍为templatized;

3)使用traits获取类型的某一特性,原理为模板参数匹配规则(类似于函数匹配),可以在编译时,确定调用对象。iterator_traits负责萃取迭代器特性,__type_traits则负责萃取型别(type)特性;

stl源码剖析_《STL源码剖析》学习笔记_第6张图片

stl源码剖析_《STL源码剖析》学习笔记_第7张图片

stl源码剖析_《STL源码剖析》学习笔记_第8张图片

第四章 序列式容器

stl源码剖析_《STL源码剖析》学习笔记_第9张图片

1)vector

采用线性连续空间;(动态空间)

支持Random Access Iterators;(随机访问,时间复杂度为O(1))

插入会导致之后的迭代器失效,如果引起扩容,则全部失效;删除会使得之后的迭代器失效;

stl源码剖析_《STL源码剖析》学习笔记_第10张图片

2)list

采用环状循环链表;(有辅助头结点)

插入/接合不会使得迭代器失效;删除只会使得当前迭代器失效;

stl源码剖析_《STL源码剖析》学习笔记_第11张图片

3)deque

采用分段连续线性空间;

允许在常数时间内对头端/尾端进行插入或删除;(当然中间的位置也可以操作,但复杂度高,设计数据的移动)

提供了Random Access Iterator,但是其内部实现复杂;

stl源码剖析_《STL源码剖析》学习笔记_第12张图片

实现描述:

  1. deque内部会维护一个map数组(存放指针指向一个连续的线性空间);
  2. 在中间删除erase元素时,会使得前面/后面的数据移动(选择需要移动数据少的方面进行移动);对于插入insert类似;
  3. 当map空间不够时,会存在map重分配策略:1)map没有占满一般时,会将map数组中的数据移动在中间,以使得前后空闲(比如一直在push_front,会出现这种情况);2)否则,进行重新分配一个两倍大的map数组,并将原来的指向连续线性空间的指针拷贝进来,并交换两个map,释放旧map;

注:在动map数组时,由于首尾迭代器会指向map对应位置,因此也需要调整首尾迭代器;

  1. 对于递增/递减迭代器,跨不同的连续线性空间时,会根据当前的map上的位置,查询到下一个map位置,再移动;
  2. deque的数据存储空间是以连续线性空间为单位的;(多余时释放)

注:连续线性空间也被称为缓冲区;

stl源码剖析_《STL源码剖析》学习笔记_第13张图片

4)stack(适配器,默认使用deque实现)

stl源码剖析_《STL源码剖析》学习笔记_第14张图片

5)queue(适配器,默认使用deque实现)

stl源码剖析_《STL源码剖析》学习笔记_第15张图片

6)heap(默认大顶堆)

实现一颗完全二叉树,且父节点大于子节点,并将其放置于vector数组中;(不提供遍历功能和迭代器)

对于插入节点,将其放置于最后的位置,然后进行percolate up上溯:将新节点与父节点比较,如果其值更大,则交换,直至不满足条件或者已达父节点;

对于删除最大节点(即堆顶节点),将其与最后一个元素的位置交换,然后进行percolate down下溯:将该节点和其较大的子节点对换,并持续下放,直至叶子节点;然后再对该叶子节点进行上溯(不能在中间直接停掉吗??)

对于make_heap产生一个堆:从下往上构建堆。

注:将一颗完全二叉树存放在数组中,第一个元素不存放数据,之后将该颗完全二叉树层次遍历放入数组中,那么存在性质:在i处的节点,其左节点必然位于2*i,其右节点必然位于2*i+1;

7)priority_queue

采用heap实现,默认为大顶堆(less);

不提供遍历和迭代器;

8)slist

单向链表;(有辅助头结点)

对于插入、删除、结合等不会使得迭代器失效;但是其中间删除/插入元素的时间复杂度为O(n),因为其需要遍历以获取当前的前一个节点;因此最好在头部进行删除/插入元素操作;

只提供push_front,而不提供push_back;

stl源码剖析_《STL源码剖析》学习笔记_第16张图片

第五章 关联式容器

1)RB-tree

stl源码剖析_《STL源码剖析》学习笔记_第17张图片

2)set/map/multiset/multimap

采用RB-tree红黑树实现;

删除/插入新元素,不会导致迭代器失效;

set/map不允许重复,multiset/multimap允许重复;

3)hash_table

线性探测(存在primary clustering问题)、二次探测(存在secondary clustering问题)、开链法;

维护一个指针数组,每一个指针代表一个链表(具有相同的hash值);

在插入数据时,会插入到同一个hash桶中的相同键值的数据旁边;(为什么这么写?)

当出现hashtable中元素个数达到阈值时(SGI是数组大小小于总元素个数时扩容),进行扩容(扩容大小为下一个质数),并将原来的数据rehash到新的表中(原来同一个桶中的数据,现在可能会hash到不同桶中,因此需要一个一个hash,这可能会导致同一个桶的数据出现翻转现象);

4)hash_set/hash_map/hash_multiset/hash_multimap

采用hash_table实现;

hash_set/hash_map不允许重复,hash_multiset/hash_multimap允许重复;

注:我用的版本中,为map/multimap/unordered_map/ unordered_ multimap…

第六章 算法

  1. lower_bound:返回一个迭代器,指向第一个不小于value的元素;(前提有序)
  2. upper_bound:返回一个迭代器,指向第一个大于value的元素;(前提有序)
  3. sort:

注:关于快排的median-of-three(三数中值):取头、尾、中央三个位置元素的中值作为pivot;

stl源码剖析_《STL源码剖析》学习笔记_第18张图片

stl源码剖析_《STL源码剖析》学习笔记_第19张图片

stl源码剖析_《STL源码剖析》学习笔记_第20张图片

自省式排序实现描述:

A. 对于要排序的元素数量大于一定值(16),并且快排递归深度没有达到阈值,则使用三数中值快排;

B. 如果快排递归到一定深度(10),则使用堆排序;

C. 对于要排序的元素数量小于等于一定值(16)时,此时不在进行排序;

D. 最后,可以得到一个基本有序的数组,因此可以使用插入排序进行最终的排序;(此时,以16个元素划分,之内无序,在之间是相对有序的)

4. equal_range:寻找value所处的范围;(前提有序)

实现描述:可以在使用二叉搜索找到value后,应用lower_bound查前半部分的下界,以及应用upper_bound查后半部分的下界;

5. nth_element:寻找第n大的元素,并使得前面区域的元素不小于后面的区域的元素;

实现描述:使用median-of-3 partitioning将整个序列分割为更小的左、右子序列;如果nth迭代器位于左子序列,就再对左子序列进行分割,否则再对右子序列进行分割。依此类推,知道分割后的子序列不大于3,便对这个待分割的子序列进行插入排序;

本质上是部分快排;

6. merge sort:归并排序

stl源码剖析_《STL源码剖析》学习笔记_第21张图片

你可能感兴趣的:(stl源码剖析,stl源码剖析,pdf,stl源码剖析pdf,stl源码剖析带目录,stl源码剖析有必要看吗)