Boolan网——C++微专业第八周学习笔记

(1)容器deque
<1>deque的模板形式

template
inline size_t __deque_buf_size(size_t n, size_t sz)
{
    // 如果n不为0,传回n,表示buffer_size由使用者自定
    // 如果n为0,表示buffer_size使用的时预设值:如果sz(也就是sizeof(value_tyoe))小于512,传回512/sz;否则传回1
    return n != 0 ? n : (sz<512 ? size_t(512/sz):size_t(1));
}
Boolan网——C++微专业第八周学习笔记_第1张图片

在上述代码中定义了deque的首尾迭代器(start、finish)、中继器map的指针(map)、中继器尺寸(map_size)。
<2>deque的迭代器

Boolan网——C++微专业第八周学习笔记_第2张图片

迭代器中包含三个T*:cur、first、last,指向数据区域的当前位置、头位置、尾位置。
还有一个map_pointer用于指向中继器中的节点。


<3>dequed::insert()
分为三种情况:
1.如果安插位置为deque的最前端,执行push_front()执行;


2.如果安插位置为deque的最尾端,执行push_back()执行;


3.否则利用insert_aux(position,x)函数

Boolan网——C++微专业第八周学习笔记_第3张图片

<4>deque是如何模拟连续空间的?
deque利用其自身的迭代器完成对连续空间容器所能支持的运算。

Boolan网——C++微专业第八周学习笔记_第4张图片
operator-(const self& x) const
{
return difference_type(buffer_size()) * (node - x.node - 1) + (cur - first) + (x.last - x.cur);
}

两根iterator之间的buffers的总长度 = difference_type * 首尾buffers之间的buffers数量。

两根iterator之间的距离 = 两根iterator之间的buffers的总长度 + itr至其buffer末尾的长度 + x至其buffer起头的长度。

Boolan网——C++微专业第八周学习笔记_第5张图片
Boolan网——C++微专业第八周学习笔记_第6张图片
Boolan网——C++微专业第八周学习笔记_第7张图片

在上述操作符重载中使用了已经封装好的操作符。
(2)queue与stack
queue与stack不是严格的容器,而是一种适配器,这两种容器选择一种容器作为底层容器,其操作由底层容器实现。

Boolan网——C++微专业第八周学习笔记_第8张图片

在上述代码中就是采用deque作为底层容器
屏蔽部分deque的功能,使双向进出的deque变成了先进先出。

Boolan网——C++微专业第八周学习笔记_第9张图片

在上述代码中就是采用deque作为底层容器
屏蔽部分deque的功能,使双向进出的deque变成了先进后出。
stack与queue都不允许遍历,也不提供iterator迭代器。
对于底层容器,不仅仅采用deque,只要选取的底层容器能够支持所需要的操作即可。
stack和queue都可以采用list或deque作为底层容器,但是stack能够使用vector作为其底层容器,但是queue却不能。
因为在queue中的pop()函数使用的push_front,而vector不支持push_front。
同时stack和queue都不可以采用set或map作为底层容器。
(3)rb_tree
rb_tree是一种常用的平衡二元搜索树。rb_tree能够提供遍历以及迭代器iterator。按照正常的++遍历能够获取经过排序后的数据。
rb_tree用于set与map中。在rb_tree中不应当使用iterator改变元素值。
rb_tree提供了两种insertion操作:
insert_unique():表示节点的key在整个树中是独一无二的;
insert_equal():表示树中的节点key可以是重复的。

Boolan网——C++微专业第八周学习笔记_第10张图片

其遍历顺序是:5 6 7 8 10 11 12 13 15。
rb_tree的大小:


其中仿函数为0,实际上编译器编译为1。于是大小就是4+4+1 = 9。进一步补位成4的倍数,成为12。

Boolan网——C++微专业第八周学习笔记_第11张图片

(4)set与multiset

Boolan网——C++微专业第八周学习笔记_第12张图片
Boolan网——C++微专业第八周学习笔记_第13张图片

set容器的底层容器为rb_tree:
G2.9中:

Boolan网——C++微专业第八周学习笔记_第14张图片

同时将set的迭代器类型定义为const_iterator类型,这就使得set的迭代器无法修改set中的数据。
同时将set的迭代器类型定义为const_iterator类型,这就使得set的迭代器无法修改set中的数据。
VC6中:

Boolan网——C++微专业第八周学习笔记_第15张图片

set的所有操作都是直接调用底层容器中的操作,所以在一定程度上来说set也是一种container adapter(容器适配器)。
(5)map与multimap
map/multimap与set/multiset相同,都是以rb_tree作为底层容器。

Boolan网——C++微专业第八周学习笔记_第16张图片

不同的是,利用map/multimap中的恶迭代器可以改变其中元素的value,但是不能够改变元素的key。如上图所示,将user指定的key typr定义为const。

Boolan网——C++微专业第八周学习笔记_第17张图片
Boolan网——C++微专业第八周学习笔记_第18张图片

使用下标访问map对象:
map A;
A[“aa”] = 1;
将会如下执行:
(1)在A中查找键为aa的元素,未找到;
(2)将新的键值对插入A中;
(3)读取新插入的元素,将该值赋值为1。
由此可见:
如果该键已经存在与容器中,则map的下标运算与vector的下标运算是相同的,返回该键所关联的值。
当所查找的键不存在时,map容器会为该键创建一个新的元素。
(6)hash table
当分配空间足够时:


数据将会直接放置在相对应的位置。
当分配空间不足时:


比如:分配空间为10,那么15将会放置在第5个位置(15%10 = 5);与此同时编号为25的元素也会被放置在第5个位置,这样就会导致所存放的数据的重叠。
hashtable将重叠的数据形成一个list。

Boolan网——C++微专业第八周学习笔记_第19张图片

当再插入48个元素,总数为54,此时超过了buckets vector的大小,此时将会进行rehashing.

Boolan网——C++微专业第八周学习笔记_第20张图片

与以rb_tree为底层容器的容器相同,hashtable也是根据key来实现对于元素的排序,所以可以使用hashtable iterators改变元素的data,但是不能改变元素的key。

Boolan网——C++微专业第八周学习笔记_第21张图片
Boolan网——C++微专业第八周学习笔记_第22张图片

在其中HashFcn、ExtractKey、Equalkey都是仿函数。

Boolan网——C++微专业第八周学习笔记_第23张图片

hash function的目的是希望根据元素计算出一个hash code(一个可以进行modulus模数运算的值),使得元素经过hash code映射之后能够“够杂够乱够随机”地被放置在hashtable中。因为数据被放置地越乱,相互之间就越不会出现碰撞。

Boolan网——C++微专业第八周学习笔记_第24张图片

放置在hash table中为:

Boolan网——C++微专业第八周学习笔记_第25张图片

(7)unordered容器
自C++11之后,hash_set、hash_multiset、hash_map、hash_multimap变为unordered_set、unordered_multiset、unordered_map、unordered_multimap。

Boolan网——C++微专业第八周学习笔记_第26张图片

你可能感兴趣的:(Boolan网——C++微专业第八周学习笔记)