目录
1.2.2operator*() && operator->()
1.2.5operator==() && operator!=()
二、如何用哈希表搭配unordered_map和unordered_set(仿函数)
三、哈希表封装unordered_map和unordered_set(简易版)
3.2unordered_map的模拟实现(My_Unordered_Map.h)
3.3unordered_set的模拟实现(My_Unordered_Set.h)
上一篇章,学习了unordered系列容器的使用,以及哈希结构,那么这一篇章将通过哈希结构来封装unordered系列容器,来进一步的学习他们的使用以及理解为何是如此使用。其实,哈希表的封装方式和红黑树的封装方式形式上是差不多的,如果有了红黑树的封装理解经验,我相信在理解哈希封装的过程会减少负担的。当然,在使用哈希结构中采用的是更具代表的哈希桶,接下来进行封装。
一、改造哈希表
1.1模板参数列表的改造
同理模板参数列表的改造跟红黑树的改造差不多。
K:关键码类型
V:不同容器v的容器类型不同,如果是unordered_map,v代表一个键值对,如果是unordered_set,v为k
KeyOfT:因为v的类型不同,通过keyOfT取key的方式就不同 。
Hash:哈希函数仿函数对象类型,哈希函数使用除留余数法,需要将字符串类型转化为整形数字才能取模。
1.2增加哈希表迭代器操作
1.2.1哈希表迭代器框架
//前置声明,迭代器中才能定义HashTable对象
template<class K, class T, class KeyOfT, class hash>
class HashTable;
template<class K,class T,class Ref,class Ptr,class KeyOfT,class hash = HashFunc<K>>
struct _HTIterator
{
typedef _HTIterator<K,T, Ref, Ptr,KeyOfT,hash> Self;//方便作为接收迭代器操作的返回值的类型
typedef HashNode<T> Node;
typedef Node* PNode;
PNode _node;//定义节点指针,方便访问其成员来完成迭代器的操作
HashTable<K, T, KeyOfT, hash>* _ht;//定义哈希表指针,方便使用其成员来完成迭代器的操作
size_t _hashi;//记录迭代器访问的位置
_HTIterator(PNode node, HashTable<K, T, KeyOfT, hash>* ht,size_t hashi)
:_node(node)
,_ht(ht)
,_hashi(hashi)
{}
//....
};
1.2.2operator*() && operator->()
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(_node->_data);
}
1.2.3operator++()
Self& operator++()
{
if (_node->_next)//下一个元素不为空
{
_node = _node->_next;
}
else
{
/*hash hs;
KeyOfT oft;
int hashi = hs(oft(this->_data) % _tables.size());*/
//寻找下一个不为空的桶
++_hashi;
while(_hashi < _ht->_tables.size())
{
if (_ht->_tables[_hashi] != nullptr)
{
_node = _ht->_tables[_hashi];
break;
}
++_hashi;
}
//到末尾还没有找到不为空的桶
if(_hashi == _ht->_tables.size())
_node = nullptr;
}
return *this;
}
1.2.4operator--()
Self operator--()
{
PNode cur = _ht->_tables[_hashi];
//当前节点就是第一个节点
if (cur->_next == nullptr)
{
//寻找上一个非空桶
--_hashi;
while (_hashi)
{
//寻找该非空桶的最后一个元素
if (_ht->_tables[_hashi])
{
cur = _ht->_tables[_hashi];
while (cur->_next)
{
cur = cur->_next;
}
_node = cur;
break;
}
_hashi--;
}
}
else
{
while (cur->_next != _node)
{
cur = cur->_next;
}
_node = cur;
}
return *this;
}
1.2.5operator==() && operator!=()
bool operator==(const Self& x)
{
return _node == x._node;//由于没有重复的元素,直接比较节点的地址
}
bool operator!=(const Self& x)
{
return _node != x._node;
}