哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方,说起来可能感觉有点复杂,我想我举个例子你就会明白了,最典型的的例子就是字典
默认你已经实现了哈希表(开散列)
封装前的哈希代码
namespace HashBucket
{
template<class K,class V>
struct HashNode
{
pair<K, V> _kv;
HashNode* _next;
HashNode(const pair<K, V>& kv)
:_kv(kv)
, _next(nullptr)
{}
};
template<class K,class V,class Hash=HashFunc<K>>
class HashTable
{
typedef HashNode<K,V> Node;
public:
Node* Find(const K& key)//Find函数返回值一般都是指针,通过指针访问这个自定义类型的成员
{
Hash hash;
if (_tables.size() == 0)//表的大小为0,防止取余0
{
return nullptr;
}
size_t index = hash(key) % _tables.size();//找到桶号
Node* cur = _tables[index];
while (cur)
{
if (cur->_kv.first == key)
{
return cur;
}
else
{
cur = cur->_next;
}
}
return nullptr;
}
size_t GetNextPrime(size_t prime)
{
const int PRIMECOUNT = 28;
static const size_t primeList[PRIMECOUNT] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
//ul表示unsigned long
size_t i = 0;
for (; i < PRIMECOUNT; ++i)
{
if (primeList[i] > prime)
return primeList[i];
}
return primeList[i];
}
bool Insert(const pair<K, V>& kv)
{
if (Find(kv.first))//有相同的key直接返回false
{
return false;
}
//if(_n==0||_n==_tables.size())
Hash hash;
if (_n == _tables.size())//最开始_n为0,而_tables.size()也为0所以可以简化为一行代码
{
//增容
//size_t newSize = _tables.size() == 0 ? 10 : _tables.size() * 2;
size_t newSize = GetNextPrime(_tables.size());
vector<Node*>newTables;
newTables.resize(newSize, nullptr);
for (int i = 0; i < _tables.size(); i++)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;//记录下一个位置
size_t index = hash(cur->_kv.first) % newTables.size();
cur->_next = newTables[index];//cur当头
newTables[index] = cur;//更新vector里的头
cur = next;
}
}
_tables.swap(newTables);//把新表的数据放入旧表中
}
size_t index = hash(kv.first) % _tables.size();//算出桶号
//头插
Node* newNode = new Node(kv);
newNode->_next = _tables[index];
_tables[index]=newNode;
++_n;//别忘记更新有效数据的个数
return true;
}
bool Erase(const K& key)
{
//if (!Find(key))//找不到这个元素
// 这么写也可以,但是后面删除的过程中会顺带遍历整个桶
//{
// return false;
/
沃梦达教程
本文标题为:C++深入探究哈希表如何封装出unordered_set和unordered_map


基础教程推荐
猜你喜欢
- C/C++编程中const的使用详解 2023-03-26
- C语言基础全局变量与局部变量教程详解 2022-12-31
- 详解c# Emit技术 2023-03-25
- C语言 structural body结构体详解用法 2022-12-06
- 一文带你了解C++中的字符替换方法 2023-07-20
- C利用语言实现数据结构之队列 2022-11-22
- C++中的atoi 函数简介 2023-01-05
- 如何C++使用模板特化功能 2023-03-05
- C++使用easyX库实现三星环绕效果流程详解 2023-06-26
- C++详细实现完整图书管理功能 2023-04-04