您的位置:首页 > 其它

23 hashtable&unordered_set&unordered_map深度探索

2017-12-09 21:26 791 查看

1、概述

STL中的另一种关联式容器unordered_set/multiset,unordered_map/multimap是以hashtable(散列表)为底层结构的。下面对hashtable的数据结构做一个详细的介绍。

2、G2.9中hashtable的工作原理



解析:

a、hashtable是由bucket篮子及篮子指向的单向链表元素组成。其中bucket是vector类型,单向链表存放数据元素。

b、当向hashtable中插入一个对象时,首先要计算该对象放于哪个篮子中。即通过hash_function来计算hash_code,如通常开始篮子的大小是53,当存放的数据类型是int数值55,则通过modulus运算:55 % 53 = 2,计算结果2就是表明元素55存放第#2篮子,依次类推。当计算的对象不是int数值类型时,就需要hash_function来自己定义如何计算hash_code。

c、当某个篮子指向的单向链表元素的个数等于篮子bucket大小时,buckets的大小会按照一定规则进行扩充(接近2倍的方式),此时原来存放的元素进行重新modulus运算,并重新放置。这么做是保证每个单向链表的长度不会太多,能提高元素的访问效率。

3、G2.9中hashtable的数据结构



解析:

a、hashtable的模板类参数有6个,除了value、key、ExtractKey、alloc外。有一个hashfucn方法和EqualKey方法用来计算hash_code和比较key是否相等。

b、正如hashtable工作原理介绍,hashtable的数据保护vector类型的buckets。还有_hashtable_node的类型包括存放指向下个元素的指针和数据。

c、hashtable有自己的迭代器_hashtable_iterator,里面包含一个指向node的指针和指向hashtable本身的指针。这就符合hashtable是由bucket和元素链表组成。

4、hashtable的使用示例



解析:

a、声明一个C类型字符串的hashtable,其中hashcode采用标准库中的hash<const char*>类型,详细结构如下,是通过函数_str_hash_string()函数来不计算

不同字符串代表的hashcode:



b、判断两个key是否相同,使用了c字符串中的strcmp()函数,当字符串相同返回true来判断。

c、hashtable通过方法insert_unique(),来插入不能重复字符串,在unordered_set正是以hashtable为底层结构的这种方法来进行key的唯一。

5、unordered_set/multiset和unordered_map/multimap

unordered_set/multiset和unordered_map/multimap正是以hashtable为底层结构,然后根据unordered_set和unordered_map的不同特性,来使用hashtable.这和

上篇介绍的set和map以rb_tree为底层结构是一样的。这边就不再介绍,如下是简单的使用unordered_set的例子:

#include <iostream>
using namespace std;
#include <unordered_set>

int _tmain(int argc, _TCHAR* argv[])
{
unordered_set<int> uset;//插入类型为int
for (int i = 0; i < 100; ++i){
uset.insert(i);
}
cout << "size(): " << uset.size() << endl;//元素的个数
cout << "bucket_count
8f77
(): " << uset.bucket_count() << endl;//篮子的长度
for (unsigned i = 0; i < 512; i++){
cout << "bucket #" << i << "has " << uset.bucket_size(i) << "elements" << endl;//计算篮子中单向链表元素的个数
}
return 0;
}
/*部分测试结果:
size(): 100
bucket_count(): 512
bucket #0has 0elements
bucket #1has 1elements
bucket #2has 1elements
bucket #3has 1elements
bucket #4has 1elements
bucket #5has 0elements
bucket #6has 1elements
bucket #7has 1elements
bucket #8has 1elements
bucket #9has 0elements
bucket #10has 0elements
bucket #11has 0elements
bucket #12has 0elements
...
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: