方法一:类似STL中hashtable的实现:
摘录自《STL源码剖析》5.7.7节
hashtable以质数来设计表格大小,预先计算好了28个质数,大约都是两倍的关系递增,查询28个质数中,“最接近且大于元素数目”的数字作为vector的长度,如果需要重新分配,则分配下一个质数长度的vector。Bucket所维护的linked list不采用STL的list或者slist(直接指针操作),而至于bucket则使用vector来完成。
开链法处理冲突;
对字符串类似的hash函数的计算如下:
hash(char *s)
{
unsigned long h=0;
for( ; *s ; ++s)
h=5*h+*s;
return size_t(h);
}
对于int,long型,hash函数直接返回
hashable实现容器对比:
hash_set:与set的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_map:与map的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_multimap:与multimap的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_multiset:与multiset的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
方法二:出自陈皓博客《哈希表心得》,
链接:http://blog.csdn.net/haoel/article/details/2863
hash表的组织方式和处理冲突的方法和STL相同,不同的是:
(1)哈希表尺寸的变化方式
下面的数库是哈希表变化尺寸时尺寸大小的一个列表。
static int prime_array[] = {
17, /* 0 */
37, /* 1 */
79, /* 2 */
163, /* 3 */
331, /* 4 */
673, /* 5 */
1361, /* 6 */
2729, /* 7 */
5471, /* 8 */
10949, /* 9 */
21911, /* 10 */
43853, /* 11 */
87719, /* 12 */
175447, /* 13 */
350899, /* 14 */
701819, /* 15 */
1403641, /* 16 */
2807303, /* 17 */
5614657, /* 18 */
11229331, /* 19 */
22458671, /* 20 */
44917381, /* 21 */
89834777, /* 22 */
179669557, /* 23 */
359339171, /* 24 */
718678369, /* 25 */
1437356741, /* 26 */
2147483647 /* 27 (largest signed int prime) */
};
#define PRIME_ARRAY_SIZE (28)
STL中采用的是:
static unsigned int
getHashIndex(hTab *tabPtr, const char *key)
{
unsigned int ha = 0;
while (*key)
ha = (ha * 128 + *key++) % tabPtr->size;
return ha;
}
(其中key是一个字符串,hTab就是一个哈希表结构, tabPtr->size是哈希表数组的大小)
补充内容:摘录自《Boost程序库探秘——深度解析C++准标准库》第4章BOOST库中的hash函数是对STL的hash函数的扩充。
stl:仅对char *,char,short,long,,int等类型处理,对string,double,float,用户必须自定义哈希函数。
而boost库则增加了:
(1)对stl不支持的类型,如float/double/string/和vector/list等标准容器
(2)还可以对自定义类型计算哈希值
步骤:
1, 成员函数定义hash_value()函数
2, 外部实现重载的自由函数hash_value()函数
(3)利用hash_combine(),hash_range()组合散列值
例如:要求对类demo_class的散列值的计算方式是用0作为seed(注seed可为任意值),然后逆序计算v中的所有元素。