hashtable的桶子(buckets)与节点(nodes)。
hash table使用开链法完成hash table的图形表述。hash table表格内的元素为桶子(bucket),此名称的大约意义是,表格内的每个单元,涵盖的不只是节点,甚至可能是一“桶”节点。
template<class Value>
struct __hashtable_node
{
__hashtable_node * next;
Value val;
}
hashtable的迭代器
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_iterator {
//typedef 定义
typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
hashtable;
typedef __hashtable_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
iterator;
typedef __hashtable_const_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
const_iterator;
typedef __hashtable_node<Value> node;
typedef forward_iterator_tag iterator_category; //迭代器类型
typedef Value value_type; //迭代器所指对象的型别
typedef ptrdiff_t difference_type; //两个迭代器之间的距离
typedef size_t size_type;
typedef Value& reference;
typedef Value* pointer;
node* cur; //迭代器目前所指节点
hashtable* ht; //保持对容器的连结关系(因为可能需要从bucket跳到bucket)
/*构造函数*/
__hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {}
__hashtable_iterator() {}
/*运算符重载*/
reference operator*() const { return cur->val; }
pointer operator->() const { return &(operator*()); }
iterator& operator++(); //前缀++
iterator operator++(int); //后缀++
bool operator==(const iterator& it) const { return cur == it.cur; }
bool operator!=(const iterator& it) const { return cur != it.cur; }
};
hashtable迭代器必须永远维持着整个“buckets vector”的关系,并记录目前所指的节点。其前进操作是首先尝试从目前所指的节点出发,前进一个位置(节点),由于节点被安置于list内,所以利用节点的next指针即可以轻易达成前进操作。如果目前节点正巧是list的尾端,就跳置下一个bucket身上,那正是指向下一个list的头部节点。
/*前缀++*/
template <class V, class K, class HF, class ExK, class EqK, class A>
__hashtable_iterator<V, K, HF, ExK, EqK, A>&
__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++()
{
const node* old = cur;//保存当前位置
cur = cur->next;//更新为当前bucket链表中的下一个节点
if (!cur) {//如果该节点恰好为list 的尾端
size_type bucket = ht->bkt_num(old->val);//通过散列函数查找键值对应的bucket
while (!cur && ++bucket < ht->buckets.size())//根据元素值定位下一个bucket的起头处
cur = ht->buckets[bucket];
}
return *this;
}
/*后缀++,返回的是++之前的数值*/
template <class V, class K, class HF, class ExK, class EqK, class A>
inline __hashtable_iterator<V, K, HF, ExK, EqK, A>
__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
{
iterator tmp = *this;
++*this;//调用operator++
return tmp;//返回自增前的值
}
hashtable的迭代器没有后退操作(operator--()),hashtable也没有定义所谓的逆向迭代器。
参考:https://www.kancloud.cn/digest/stl-sources/177282