红黑树(set、map、multiset、multimap的底层机制实现)
每个节点不是红色就是黑色。
根节点为黑色。
如果节点为红,其子节点必须为黑。
任一节点至 NULL 的任何路径,所含之黑节点数必须相同。
- 插入节点
根据 X 的插入位置及外围节点的颜色,有了四种考虑。
- 一个由上而下的程序
假设新增节点为A,那么就沿着 A 的路径,只要看到有某节点 X 的两个子节点皆为红色,就把 X 改为红色,并把两个子节点改为黑色。
- RB-tree 的迭代器
前进和后退操作均调用基层迭代器。
- RB-tree 的元素操作
RB-tree 提供两种插入操作:insert_unique() 和 insert_equal()。
set 的特性是,所有元素会根据元素的键值自动被排序。
map 的特性是,所有元素会根据元素的键值自动被排序。
multiset 的特性及用法和 set 完全相同,唯一差别在于它允许键值重复。
multimap 的特性及用法和 map 完全相同,唯一差别在于它允许键值重复。
hash table
- 使用 hash table 可能会带来一个问题:不同的元素被映射到相同的位置。
- 解决碰撞的方法:线性探测、二次探测、开链,等。
- buckets 聚合体,以 vector 完成,以便有动态扩充能力。
- 迭代器由容器自己实现,是一种forward iterator,没有逆向迭代器
- hashtable以质数来设计表格大小,预先计算好了28个质数,大约都是两倍的关系递增,查询28个质数中,“最接近且大于元素数目”的数字作为vector的长度,如果需要重新分配,则分配下一个质数长度的vector。Bucket所维护的linked list不采用STL的list或者slist(直接指针操作),而至于bucket则使用vector来完成。
- hashtable设计的容量和buckets vector的大小一样。因此如果数目超过了,就需要重新建立:新建一个temp,将原来hashtable中的元素一个一个切割出来插入到新的temp的适当位置,全部插完后交换hashtable和temp。同时释放temp的内存。
- hashtable有一些无法处理的型别,比如string,double,float。除非用户为那些型别写了相应的hash function。
Hash_Map,Hash_Set,Hash_MultiSet,Hash_MultiMap
这些容器和前面介绍的一一对应,只不过这些是以hash_tabel为底层实现机制的。
**底层机制决定了这两组容器的区别:
- RB-tree组对元素实现排序,而hash_map组没有;
- RB-tree的查找时间复杂度为lg(n),而hash_map组为常数时间;
- RB-tree组在空间利用上,不会浪费结点,而hash_map组可能会有一些空置桶。
- Hash_multiset和Hash_multimap插入使用的是inset_equal。其它操作与multiset和multimap相同。**