hello~ 很高兴见到大家! 这次带来的是C++中关于哈希表这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢? 个 人 主 页: 默|笙

接上回<开放地址法实现博客>

它的流程基本和开放地址法的实现差不多: 搭建框架->实现Insert(解决普通插入+扩容+去重)、Find、Erase函数->实现能够将key转化为size_t类型的仿函数。
template<class K, class V>
struct Node
{
Node(const pair<K, V>& kv)
:_kv(kv)
,_next(nullptr)
{ }
pair<K, V> _kv;
Node<K, V>* _next;
};
template<class K, class V, class Hash = HashFunc<K>>
class HashBacket
{
typedef Node<K, V> Node;
public:
HashBacket()
:_tables(53, nullptr)
,_count(0)
{ }
//析构函数,需要释放所有节点
~HashBacket()
{
int i = 0;
Node* cur = _tables[i];
while (i < _tables.size())
{
while (cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
i++;
}
}
private:
vector<Node*> _tables;
size_t _count;
};inline unsigned long __stl_next_prime(unsigned long n)
{
// Note: assumes long is at least 32 bits.
static const int __stl_num_primes = 28;
static const unsigned long __stl_prime_list[__stl_num_primes] =
{
53, 97, 193, 389, 769,
1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433,
1572869, 3145739, 6291469, 12582917, 25165843,
50331653, 100663319, 201326611, 402653189, 805306457,
1610612741, 3221225473, 4294967291
};
const unsigned long* first = __stl_prime_list;
const unsigned long* last = __stl_prime_list + __stl_num_primes;
const unsigned long* pos = lower_bound(first, last, n);
return pos == last ? *(last - 1) : *pos;
}
bool Insert(const pair<K, V>& kv)
{
//去重
if (Find(kv.first))
{
return false;
}
Hash hs;
//扩容
if (_count == _tables.size())
{
vector<Node*> newtable;
newtable.resize(__stl_next_prime(_tables.size() + 1));
for (int i = 0; i < _tables.size(); i++)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
size_t hashi = hs(cur->_kv.first) % _tables.size();
cur->_next = newtable[hashi];
newtable[hashi] = cur;
cur = next;
}
_tables[i] = nullptr;
}
_tables.swap(newtable);
}
//插入数据
size_t hashi = hs(kv.first) % _tables.size();
Node* newnode = new Node(kv);
newnode->_next = _tables[hashi];
_tables[hashi] = newnode;
_count++;
return true;
}Node* Find(const K& key)
{
Hash hs;
int hashi = hs(key) % _tables.size();
Node* cur = _tables[hashi];
while (cur)
{
if (cur->_kv.first == key)
{
return cur;
}
cur = cur->_next;
}
return nullptr;
}bool Erase(const K& key)
{
Hash hs;
int hashi = hs(key) % _tables.size();
Node* it = Find(key);
if (it)
{
Node* next = it->_next;
if (_tables[hashi] == it)
{
delete it;
_tables[hashi] = next;
}
else
{
Node* prev = _tables[hashi];
while (prev->_next != it)
{
prev = prev->_next;
}
delete it;
prev->_next = next;
}
_count--;
return true;
}
else
{
return false;
}
}template<class K>
struct HashFunc
{
size_t operator()(const K& key)
{
return (size_t)key;
}
};
template<>
struct HashFunc<string>
{
size_t operator()(const string& str)
{
size_t hash = 0;
for (auto ch : str)
{
hash += ch;
hash *= 131;
}
return hash;
}
};今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 让我们共同努力, 一起走下去!