template<class K>
struct keyOfValue
{
const K& operator()(const K& key)
{
return key;
}
};
//开散列: 指针数组 + 单链表
template<class V>
struct HashNode
{
V _value;
HashNode<V>* _next;
HashNode(const V& _val = V())
:_value(val)
,_next(nullptr)
{}
};
//前置声明
template<class K, class V, class KeyOfValue, class HF>
class HashTable;
template<class K, class V, class KeyOfValue, class HF>
struct HashIterator
{
typedef HashNode<V> Node;
typedef HashIterator<K, V, KeyOfValue, HF> Self;
typedef HashTable<K, V, KeyOfValue, HF> HT;
Node* _node;
HT* _ht;
HashIterator(Node* node, HT* ht)
:_node(node)
,_ht(ht)
{}
V& operator*()
{
return _node->_value;
}
V* operator&()
{
return &_node->_value;
}
bool operator!=(const Self& it)
{
return _node != it._node;
}
Self& operator++()
{
if (_node->_next)
{
_node = _node->_next;
}
else
{
//找到下一个非空链表的头结点
// 1. 定位当前节点在哈希表中的位置
//kov: 获取value的key
KeyOfValue kov;
//hf: 获取key转换之后的整数
HF hf;
size_t idx = hf(kov(_node->_value) % _ht->_table.size();
// 2. 从表中的下一个位置开始查找第一个非空链表的头结点
++idx;
Node* cur = _ht->_table[idx];
for (; idx < _ht->table.size(); idx++)
{
if (_ht->table[idx])
{
_node = _ht->table[idx];
break;
}
}
// 3. 判断是否找到一个非空的头结点
if (idx == _ht->table.size())
_node = nullptr;
}
return *this;
}
};
template<class K, class V, class KeyOfValue, class HF>
class HashTable
{
public:
//迭代器声明为友元类
template <class K, class V, class KeyOfValue, class HF>
friend struct HashIterator;
typedef HashNode<V> Node;
typedef HashIterator<K, V, KeyOfValue, HF> iterator;
iterator begin()
{
//第一个非空链表的头结点
for (size_t i = 0; i < _table.size(); i++)
{
Node* cur = _table[i];
if (cur)
return iterator(cur, this);
}
return iterator(nullptr.this);
}
iterator end()
{
return iterator(nullptr, this);
}
pair<iterator, bool> insert(const V& value)
{
checkCapacity();
//1. 计算位置
KeyOfValue kov;
HF hf;
int idx = hf(kov(value)) % _table.size();
//2. 搜索key是否已经存在
Node* cur = _table[idx];
while (cur)
{
if (kov(cur->_value) == kov(value))
return make_pair(iterator(cur, this), false);
cur = cur->_next;
}
//3. 插入: 头插
cur = new Node(value);
cur->_next = _table[idx];
_table[idx] = cur;
++_size;
return make_pair(iterator(cur, this), true);
}
void checkCapacity()
{
if (_size == _table.size())
{
size_t newSize = _size == 0 ? 5 : 2 * _size;
vector<Node*> newHt;
newHt.resize(newSize);
KeyOfValue kov;
HF hf;
//遍历旧表中的非空单链表
for (size_t i = 0; i < _table.size(); i++)
{
Node* cur = _table[i];
//遍历当前链表
while (cur)
{
//0.记录旧表中的下一个元素
Node* next = cur->_next;
//1.计算新的位置
int idx = hf(kov(cur->_value)) % newHt.size();
//2.头插
cur->_next = newHt[idx];
newHt[idx] = cur;
//3.处理下一个元素
cur = next;
}
_table[i] = nullptr;
}
_table.swap(newHt);
}
}
Node* find(const K& key)
{
if (_table.size() == 0)
return nullptr;
HF hf;
int idx = hf(key) % _table.size();
Node* cur = _table[idx];
KeyOfValue kov;
while (cur)
{
if (kov(cur->_value) == key)
return cur;
cur = cur->_next;
}
return nullptr;
}
bool erase(const K& key)
{
HF hf;
int idx = hf(key) % _table.size();
Node* cur = _table[idx];
//单链表删除逻辑
Node* prev = nullptr;
KeyOfValue kov;
while (cur)
{
if (kov(cur->_value) == key)
{
//删除
//判断删除的是否为头结点
if (prev == nullptr)
{
_table[idx] = cur->_next;
}
else
{
prev->_next = cur->_next;
}
delete cur;
_size--;
return true;
}
else
{
prev = cur;
cur = cur->_next;
}
}
return false;
}
private:
vector<Node*>_table;
size_t _size = 0;
};
//字符转换为整数
struct StrToInt
{
size_t operator()(const string& str)
{
size_t hash = 0;
for (const auto& ch : str)
{
hash = hash * 131 + ch;
}
return hash;
}
};
template<class K>
struct hashFun
{
size_t operator()(const K& key)
{
return key;
}
};
template<class K, class V, class HF = hashFun<K>>
class UnorderedMap
{
struct MapKeyOfValue
{
const K& operator()(const pair<K, V>& value)
{
return value.first;
}
};
public:
typedef typename HashTable<K, pair<K, V>, MapKeyOfValue, HF>::iterator iterator;
pair<iterator, bool> insert(const pair<K, V>& value)
{
return _ht.insert(value);
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = _ht.insert(make_pair(key, V()));
return ret.first->second;
}
private:
HashTable<K, pair<K, V>, MapKeyOfValue, HF> _ht;
};
template<class K, class HF = hashFun<K>>
class UnorderedSet
{
struct SetKeyOfValue
{
const K& operator()(const K& value)
{
return value;
}
};
public:
typedef typename HashTable<K, K, keyOfValue, HF>::iterator iterator;
iterator begin()
{
return _ht.begin();
}
iterator end()
{
return _ht.end();
}
pair<iterator, bool> insert(const K& value)
{
return _ht.insert(value);
}
private:
HashTable<K, K, SetKeyOfValue, HF> _ht;
};
哈希表开散列哈希桶实现,unordered_map和unordered_set的模拟实现
最新推荐文章于 2024-06-26 22:51:47 发布