本部分包括hashtable介绍,和C++11讲得一样,只包括一些基本概念。
一、hashtable原理
不同编译器实现不同,这里讲的是GNU的实现。G2.9的hashtable就是使用链地址法解决冲突的哈希表,表长是一个素数,开始值是53,当元素个数超过表长时会自动扩容为大概原先两倍的一个素数。源码如下所示:
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey,
class Alloc = alloc>
class hashtable{
public:
typedef HashFcn hasher;
typedef EqualKey key_equal;
typedef size_t size_type;
private:
hasher hash;
key_equal equals;
ExtractKey get_key;
typedef __hashtable_node<Value> node;
vector<node*, Alloc> buckets;
size_type num_elements;
public:
size_type bucket_count() const { return buckets.size(); }
......
};
template <class Value>
struct __hashtable_node{
__hashtable_node* next;
Value val;
};
hashtable的几个模板参数:Value指表中放的实际元素,对set来说是Key,对map来说是pair;Key不用解释;HashFcn是哈希函数;ExtractKey是指如何从Value中提取出Key;EqualKey顾名思义,代表比较Key相等的可调用对象的类型;Alloc是分配器。
__hashtable_node指的是链表的节点,__hashtable_iterator里面含有一个指向链表节点的指针,还包含一个整个hashtable的指针,这样在走到某个链表的终点后能回到整个哈希表。
哈希函数以前提过,就是一个泛化的空模板类,然后定义了一大堆特化版本。