一、红黑树(RB-Tree)---map,set,multimap,multiset底层使用红黑树
Red-Black tree(红黑树)是平衡二分搜索树(balanced binary search tree)中常被使用的一种。平衡二分搜索树的特性:排列规则有利search和insert,并保持适度平衡---无任何结点过深。
RB-Tree提供遍历操作及iterators。
按正常规则(++ite)遍历,便能获得排序状态(sorted)。
我们不应该使用RB-Tree的iterators改变元素值(因为元素有其严谨的排列规则)。变成层面并未阻止此事。如此设计是正确的,因为RB-Tree即将为set何map服务(作为其底层支持),而map允许元素的data被改变,只有元素的key才是不可被改变的。
RB-Tree提供两种insertion操作:insert_unique()和insert_equal()。前者表示节点的key一定在整个tree中独一无二,否则安插失败;后者表示节点的key可重复。
具体设计代码
4.9版本的Rb_tree
二、容器set和multiset,底层容器使用的是红黑树(rb_tree)
set/multiset以rb_tree为底层结构,因此有元素自动排序特性。排序的依据是key,而set/multiset元素的value和key合一:value就是key。
set/multiset提供遍历操作及iterators。按正常规则(++ite)遍历,便能获得排序状态(sorted)。
我们无法使用set\multiset的iterators改变元素值(因为key有其严谨的排列规则)。set\multiset的iterator是其底部的rb_tree的const iterator,就是为了禁止用户对元素赋值。
set元素的key必须独一无二,因此其insert()用的是rb_tree的insert_unique()。
multiset元素的key可以重复,因此其insert()用的是rb_tree的insert_qeual()。
set的所有操作,都是底层容器t的操作,从这层意义看,set未尝不是个容器适配器(container adapter)。
multiset测试例子
三、容器map和multimap,底层容器使用的是红黑树(rb_tree)
map/multimap以rb_tree为底层结构,因此有元素自动排序的特性。排序的依据是key。
map/multimap提供遍历操作及iterators。按正常规则(++ite)遍历,便能获得排序状态(sorted)。
我们无法使用map/multimap的iterators改变元素的key(因为key有其严谨的排列规则),但可以用它来改变元素的data。因此map/multimap内部自动将用户指定的key type设为const,如此便能禁止用户对元素的key赋值。
map元素的key必须独一无二,因此其insert()用的是rb_tree的insert_unique()。
multimap元素的key可以重复,因此其insert()用的是rb_tree的insert_euqal()。
map独特的operator[]
如果找到索引中的元素,则返回索引的iterator;如果没有找到,则根据索引创建一个,插入到map中。
lower_bound是二分查找(binary search)的一种版本,试图在sorted[first,last)中寻找元素value。若[first,last)拥有与value相等的元素(s),便返回一个iterator指向其中第一个元素。如果没有这样的元素存在,便返回【假设该元素存在时应该出现的位置】。也就是说它会返回iterator指向第一个【不小于value】的元素。如果value大于[first,last)内的任何元素,将返回last。换句话说,lower_bound返回的是【不破坏排序得以安插value的第一个适当位置】。
mapped_type&
operator[](const key_type& __k)
{
// ....
iterator __i = lower_bound(__k);
if(__i == end() || key_comp()(__k,(*__i).first))
__i = insert(__i,value_type(__k,mapped_typed())); // C++ 201103L之前的版本
return (*__i).second;
}
multimap测试例子