哈希冲突——开散列的实现
程序员文章站
2022-03-15 19:37:44
...
开散列解决哈希冲突的方法是通过Key值计算出在哈希表中的存储位置,计算方法同之前的闭散列一样,Key%Capacity的值为在哈希表中的存储位置。
若两个键值对计算出来的位置相同,就把这两个键值对通过单链表链接(头插的形式)起来存储在这个位置上,这称为哈希桶。链表的头结点存储在哈希表中。
开散列的实现:
template <class K,class V>
struct HashNode
{
HashNode(const pair<K, V>& data = pair<K, V>())
:_data(data)
, _next(nullptr)
{}
pair<K, V> _data;
HashNode<K, V>* _next;
};
template <class K,class V>
class HashTable
{
public:
typedef HashNode<K, V> Node;
typedef Node* pNode;
HashTable(size_t N = 10)
{
_ht.resize(N);
_size = 0;
}
bool Insert(const pair<K, V>& data)
{
//checkCapacity
checkCapacity();
//计算位置
int index = data.first%_ht.size();
//遍历单链表
pNode cur = _ht[index];
while (cur)
{
if (cur->_data.first == data.first)
return false;
cur = cur->_next;
}
//带头结点的插入:头插 _ht[index]--->header
//newNode->next=header
//header=newNode
cur = new Node(data);
cur->_next = _ht[index];
_ht[index] = cur;
++_size;
return true;
}
void checkCapacity()
{
if (_size == _ht.size())
{
size_t newC = _ht.size() == 0 ? 10 : 2 * _ht.size();
vector<pNode> newHt;
newHt.resize(newC);
for (int i = 0; i < _ht.size(); ++i)
{
//单链表头结点
pNode cur = _ht[i];
//遍历单链表
while (cur)
{
pNode next = cur->_next;
//重新计算在新表中的位置
int index = cur->_data.first%newHt.size();
//头插
cur->_next = newHt[index];
newHt[index] = cur;
cur = next;
}
_ht[i] = nullptr;
}
swap(_ht, newHt);
}
}
pNode find(const K& key)
{
int index = key%_ht.size();
pNode cur = _ht[index];
while (cur)
{
if (cur->_data.first == key)
return cur;
cur = cur->_next;
}
return nullptr;
}
bool Erase(const K& key)
{
int index = key%_ht.size();
pNode cur = _ht[index];
pNode parent = nullptr;
while (cur)
{
//删除
if (cur->_data.first == key)
{
if (parent == nullptr)
{
_ht[index] = cur->_next;
}
else
{
parent->_next = cur->_next;
}
delete cur;
--_size;
return true;
}
parent = cur;
cur = cur->_next;
}
}
private:
//指针数组
vector<pNode> _ht;
size_t _size;
};
void testHashTable()
{
HashTable<int, int> _ht;
_ht.Insert(make_pair(1, 1));
_ht.Insert(make_pair(3, 3));
_ht.Insert(make_pair(6, 6));
_ht.Insert(make_pair(0, 0));
_ht.Insert(make_pair(10, 10));
_ht.Insert(make_pair(13, 13));
_ht.Insert(make_pair(16, 16));
_ht.Erase(10);
}
int main()
{
testHashTable();
return 0;
}
代码测试过啦!!
上一篇: 当初和我结婚什么感觉
下一篇: 预处理指令