STL之hashtable

        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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值