哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方,说起来可能感觉有点复杂,我想我举个例子你就会明白了,最典型的的例子就是字典
默认你已经实现了哈希表(开散列)
封装前的哈希代码
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语言中sizeof如何在自定义函数中正常工作 2023-04-09
- Qt计时器使用方法详解 2023-05-30
- C语言qsort()函数的使用方法详解 2023-04-26
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- C语言详解float类型在内存中的存储方式 2023-03-27
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30
- Easyx实现扫雷游戏 2023-02-06
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- C++ 数据结构超详细讲解顺序表 2023-03-25
- ubuntu下C/C++获取剩余内存 2023-09-18