前言:
由于上一章我们已经模拟实现了哈希桶,这一章主要针对于这俩的迭代器进行模拟封装。
unordered_map与unordered_set
unordered_map与unordered_set的底层实现是根据哈希构建的,所以他们俩存储的数据是无序的,我们可以利用上一章的哈希桶的实现来进行封装模拟
对于两个类用同于结构封装,必不可少的的是泛型。
桶节点:
template<class T>
struct HashNode
{
HashNode<T>* _next;
T _data;
HashNode(const T& data)
:_next(nullptr)
,_data(data)
{}
};
迭代器
如下图哈希桶的具体存储是这样的,所以对于迭代器的一些运算符重载需要根据结构实现。
end()
iterator end()
{
return iterator(nullptr, this);
}
begin()
在图中的我门需要遍历全表找到表中存在的第一个值,返回此空间的地址。
iterator begin()
{
for (size_t i = 0; i < length; i++)
{
if (_tables[i])
{
return iterator(_tables[i], this);
}
}
return end();
}
运算符++
上图为例,指向一个空间时,++则是先遍历这个位置的桶,如果桶遍历完则遍历下一个有值的表位置。
Self& operator++()
{
if (_node->_next)
{
_node = _node->_next;
}
else
{
KeyOfT kt;
Hash hs;
size_t hashi = hs(kt(_node->_data)) % _ht->_table.size();
hashi++;
while (hashi < _ht->_tables.size())
{
if (_ht->_tables[i])
{
_node = _ht->_tables[i];
break;
}
hashi++;
}
if (hashi == _ht->_tables.size())
{
_node = nullptr;
}
}
return *this;
}
unordered_map结构
template<class K, class V, class Hash = HashFunc<K>>
class unordered_map
{
struct MapKeyOfT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
public:
typedef typename HashTable<K, pair<const K, V>, MapKeyOfT, Hash>::iterator iterator;
iterator begin()
{
return _ht.begin();
}
iterator end()
{
return _ht.end();
}
bool insert(const pair<K, V>& kv)
{
return _ht.Insert(kv);
}
private:
HashTable<K, pair<const K, V>, MapKeyOfT, Hash> _ht;
};
unordered_set结构
template<class K, class Hash = HashFunc<K>>
class unordered_set
{
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
public:
typedef typename HashTable<K, const K, SetKeyOfT, Hash>::iterator iterator;
iterator begin()
{
return _ht.begin();
}
iterator end()
{
return _ht.end();
}
bool insert(const K& key)
{
return _ht.Insert(key);
}
private:
HashTable<K, const K, SetKeyOfT, Hash> _ht;
};