每笔数据都是一个键值对(key-value-pair)。当元素被插入到关联式容器中时,容器内部结构便依照其键值大小,以某种特定规则将这个元素放置于适当位置。关联容器没有所谓的头尾,所以不会有所谓的push_back()、push_front()、pop_back()、pop_front()这种操作行为。
其底层实现结构为RB-tree。
常用方法如下:
insert //返回pair
begin
end
find //一般应使用这个,其查找速度为lgn,要好于算法库的find函数
swap
key_compare //键值比较函数,默认使用less
value_compare //对于set来说和key_compare一样
erase //参数可以是迭代器,键值,迭代器区间
upper_bound //返回指向最大值的迭代器
lower_bound //返回指向最小值的迭代器
equal_range //return pair
multise是t允许重复的键值的set(set调用的是RB-tree的insert_unique,而map调用的是insert_equal)。
于set的实现类似,使用也类似。其在set方法的基础上增加了 [],[]返回的结果既可作为左值,也可作为右值。multimap允许重复的键值。可以把set当成键和值一样的map。
stl采用拉链法解决冲突其由vector和list结构构成。其中vector内的元素称为bucket,bucket下链接了bucketlist。这边bucket所维护的linked list并不采用STL的list或slist,而是自行维护的hash table node。vector充当着buckets的聚合体,以便使hashtable具有动态扩充的能力。其示意图如下(摘自侯捷的”stl源码剖析”):
stl中的hashtable重建条件:当元素个数size(把新增元素计入后)>bucketvector的大小时,则重建hashtable,即采用更大的vector(hashtable内维护了一个升序的质数数组(起始元素为53),vector的大小将扩充为接近且较大的质数)。然后对hashtable中的元素进行重映射。
stl中的hashtable只为char intlong short 和char *类型定义了hash函数,其中char *的转换函数如下(位于stl_hash_fun.h文件中):
template struct hash {};
inline size_t __stl_hash_string(const char*__s)
{
unsigned long __h = 0;
for( ; *__s; ++__s)
__h = 5*__h + *__s;
return size_t(__h);
}
而其余类型只是简单地返回真实值:如int类型的hash函数为
__STL_TEMPLATE_NULL struct hash{
size_t operator()(int __x) const { return __x; }
};
而计算元素在hashtable中的位置是通过调用:
size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
{
return _M_hash(__key) % __n;
}
其中 _M_hash 即所指定的hash函数。
tips:
SGIhashtable无法处理上述所列各项型别以外的元素,例如string,double, float。欲处理这些型别,用户必须自行定义相应的hash function,对const char *类型,不能沿用缺省的equal_to
hash_set与hash_map是以hashtable为底层容器实现的,而set和map是以RB-tree实现的,容器的差异决定了set和map的元素具有自动排序功能而hash_set没有。
hash_set的使用方式,与set完全相同,实际使用中看是否需要排序功能,需要的话就不能选择hash_set和hash_map,而需选择set和map
如果使用时没指定空间大小时,其初始大小缺省为100,这可以从stl_hash_map.h和stl_hash_set.h中了解到。
使用方式:
hash_set:
hash_set:其key和value是同一种类型,所以模版类型只需三个参数
hash_set
其中第二个和第三个参数可缺省,即使用缺省的hash
hash_map:
模版:hash_map
实例:hash_map
同set和map,hash_set及hash_map提供了与其对应的find函数,其效率高于algorithm中的find
此外,对应键值可重复的情况,stl提供了hash_multiset和hash_multimap