1 Star 0 Fork 0

wei / CPlusPlus

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
HashBucket.h 4.00 KB
一键复制 编辑 原始数据 按行查看 历史
wei 提交于 2023-04-13 00:03 . 哈希桶的模拟实现
#pragma once
#include <vector>
//template<class K>
//struct HashFunc
//{
// size_t operator()(const K& key)
// {
// return (size_t)key;
// }
//};
//
namespace HashBucket_realize
{
template<class K, class V>
struct HashNode
{
HashNode<K, V>* _next;
pair<K, V> _kv;
HashNode(const pair<K, V>& kv)
:_next(nullptr)
,_kv(kv)
{}
};
template<class K, class V, class Hash = HashFunc<K>>
class HashBucket
{
typedef HashNode<K, V> Node;
public:
HashBucket()
:_n(0)
{
//_tables.resize(10);
_tables.resize(__stl_next_prime(0));
}
~HashBucket()
{
for (size_t i = 0; i < _tables.size(); i++)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
_tables[i] = nullptr;
}
}
bool Insert(const pair<K, V>& kv)
{
if (Find(kv.first))
return false;
if (_n == _tables.size())
{
/*HashBucket<K, V, Hash> newHB;
newHB._tables.resize(_tables.size() * 2);
for (auto cur : _tables)
{
while (cur)
{
newHB.Insert(cur->_kv);
cur = cur->_next;
}
}
_tables.swap(newHB._tables);*/
vector<Node*> newTables;
//newTables.resize(2 * _tables.size(), nullptr);
newTables.resize(__stl_next_prime(_tables.size()), nullptr);
for (size_t i = 0; i < _tables.size(); i++)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next; // 保存下一节点的地址
size_t hashi = Hash()(cur->_kv.first) % newTables.size();
// 头插到新表
cur->_next = newTables[hashi]; // 这句没写
newTables[hashi] = cur;
cur = next;
}
_tables[i] = nullptr; //
}
_tables.swap(newTables);
}
size_t hashi = Hash()(kv.first) % _tables.size();
Node* newNode = new Node(kv); // 需要写构造函数,不然无法构造newNode
newNode->_next = _tables[hashi];
_tables[hashi] = newNode;
++_n;
return true;
}
Node* Find(const K& key)
{
size_t hashi = Hash()(key) % _tables.size();
Node* cur = _tables[hashi];
while (cur)
{
if (cur->_kv.first == key)
{
return cur;
}
else
{
cur = cur->_next;
}
}
return nullptr; //
}
bool Erase(const K& key)
{
size_t hashi = Hash()(key) % _tables.size();
Node* prev = nullptr;
Node* cur = _tables[hashi];
while (cur)
{
if (cur->_kv.first == key)
{
if (cur == _tables[hashi]) // 特殊情况:待删节点就是_tables[hashi]
{
_tables[hashi] = cur->_next;
}
else
{
prev->_next = cur->_next;
}
delete cur;
--_n;
return true;
}
else
{
prev = cur;
cur = cur->_next;
}
}
return false;
}
inline unsigned long __stl_next_prime(unsigned long n)
{
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
};
for (int i = 0; i < __stl_num_primes; ++i)
{
if (__stl_prime_list[i] > n)
{
return __stl_prime_list[i];
}
}
return __stl_prime_list[__stl_num_primes - 1];
}
private:
vector<Node*> _tables; // 指针数组
size_t _n;
};
void TestHB1()
{
HashBucket<int, int> hb;
int a[] = {18, 8, 7, 27, 57, 3, 38, 18, 17, 88, 38, 28};
for (auto e : a)
{
hb.Insert(make_pair(e, e));
}
hb.Insert(make_pair(5, 5));
cout << hb.Find(7) << endl;
cout << hb.Find(8) << endl;
hb.Erase(7);
cout << hb.Find(7) << endl;
}
void TestHB2()
{
string arr[] = { "苹果", "西瓜", "香蕉", "草莓", "苹果", "西瓜",
"苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
HashBucket<string, int> countHT;
//HashTable<string, int> countHT;
for (auto& e : arr)
{
auto ret = countHT.Find(e);
if (ret)
{
ret->_kv.second++;
}
else
{
countHT.Insert(make_pair(e, 1));
}
}
}
}
C++
1
https://gitee.com/Wei_st_IT/cplusplus.git
git@gitee.com:Wei_st_IT/cplusplus.git
Wei_st_IT
cplusplus
CPlusPlus
master

搜索帮助