侯捷 C++八部曲笔记汇总 - - - 持续更新 ! ! !
一、C++ 面向对象高级开发
1、C++面向对象高级编程(上)
2、C++面向对象高级编程(下)
二、STL 标准库和泛型编程
1、分配器、序列式容器
2、关联式容器
3、迭代器、 算法、仿函数
4、适配器、补充
三、C++ 设计模式
四、C++ 新标准
五、C++ 内存管理机制
六、C++ 程序的生前和死后
二、C++、STL标准模板库和泛型编程——关联式容器 (侯捷)
关联式容器
关联式容器,通过key
来找值,查找速度非常快,可以看成是小型数据库。
关联容器:set
、multiset
、map
、multimap
,实现是使用 红黑树(高度平衡二叉树)
set
的key
既是key
也是value
。
C++11
中有Unordered
容器,但他也属于关联容器,实现使用hash table
做的
rb_tree 容器
Red-Black tree
(红黑树)是平衡二叉搜索树(balanced binary search tree
)中常被使用的一种。平衡二叉搜索树的特征:排列规则有利search
和insert
,并保持适度平衡——无任何节点太深。
rb_tree
提供“遍历”操作及iterators
.
- 按正常规则(
++ite
)遍历。便能获得排序状态(sorted
)。
我们不应使用rb_tree
的iterators
改变元素值(因为元素有其严谨排序规则)。编程层面(programming leve
)并未阻止此事。
- 如此设计是正确的,因为
rb_tree
即将为set
和map
服务(作为其底层支持); - 而
map
允许元素的data
被改变,只有元素的key
才是不可以改变的。 rb_tree
提供两个insertion
操作:insert_unique()
和insert_equal()
。前者表示节点的key
一定是在整个tree
中独一无二,否则安插失败(对红黑树没有任何影响);后者表示节点的key
可以重复。
使用红黑树,有5个模板参数:
红黑树和双向链表都有一个不用的节点,双向链表是end
后面的节点,红黑树是头节点。
第三个模板参数是指定如何取出key
:
set、multiset 容器
set
/multiset
以rb_tree
为底层结构,因此有【元素自动排序】特性。
- 排序的依据是
key
,而set
/multiset
元素的value
和key
合一:value
就是key
。 set
/multiset
提供“遍历”操作及iterators
;按正常规则(++ite
)遍历,便能获得排序状态(sorted
)。- 我们无法使用
set
/multiset
的iterators
改变元素值(因为key
有其严谨的排序规则)。set
/multiset
的iterators
是其底部的RB_tree
的const-iterator
,就是为了禁止user对元素赋值。 set
元素的key
必须独一无二,因此其insert()
用的是rb_tree
的insert_unique()
。multiset
元素的key
可以重复,因此其insert()
用的是rb_tree
的insert_equal()
。
multimap
multiset<int> c;
c.insert(2);//会放在该放置的位置,放进去就会被排序
c.begin();
c.end();
c.size();
c.max_size();
c.find(target);//内置find,红黑树
map、multimap容器
map
/multimap
以rb_tree
为底层结构,因此有【元素自动排序】特性。
- 排序的依据是
key
。 map
/multimap
提供“遍历”操作及iterators
;按正常规则(++ite
)遍历,便能获得排序状态(sorted
)。- 我们无法使用
map
/multimap
的iterators
改变元素的key
(因为key
有其严谨的排序规则)。但可以用它来改变元素的data
。因此map
/multimap
内部自动将user指定的key
type
设定为const
,如此便能禁止user对元素的key
赋值。 map
元素的key
必须独一无二,因此其insert()
用的是rb_tree
的insert_unique()
。multimap
元素的key
可以重复,因此其insert()
用的是rb_tree
的insert_equal()
。
map
可以通过下标[]
来插入:
hashtable 容器
C++11
中有Unordered
容器,但他也属于关联容器,实现使用hashtable
做的 !
使用hash
表,碰撞冲突采用拉链表法.
如果元素
的个数超过bucket(篮子)
的个数,就会扩充bucket
的个数,变为当前bucket
大小的两倍附近的质数,然后每个元素rehashing
,插入。这是一条经验法则。
需要指定6个模板参数!ExtractKey
是放入的 Object
的 Key
,EqualKey
是比较函数,sizeof(hashtable)=20
。
使用 hashtable
最困难的事决定使用什么HashFcn
(HashFcn
怎么设计没人教)。
具体写一个使用hashtable
的例子:
标准库没有提供现成C++的字符串即hash<std::string>
,下面是C风格的字符串:
注:个人学习笔记,如有不足,欢迎指正!