hashtable :如何理解这种基于STL中List的hashtable实现
hashtable: how to understand this implementation of hashtable based on List in STL
我正在学习用c ++构建一个哈希表。并找到这篇文章:https://www.geeksforgeeks.org/c-program-hashing-chaining/。
它通过链接实现了简单而基本版本的哈希表(不是生产级别(以修复哈希冲突问题。
我关注了该帖子并在本地运行它,它按预期工作。实现如下:
#include <iostream>
#include <list>
using namespace std;
class Hash {
int BUCKET;
list<int> *table; // confusing point1
public:
Hash(int V);
void insertItem(int key);
void deleteItem(int key);
int hashFunction(int x) {
return (x % BUCKET);
}
void displayHash();
};
Hash::Hash(int b) {
this->BUCKET = b;
table = new list<int>[BUCKET]; // confusing point2
}
void Hash::insertItem(int key) {
int index = hashFunction(key);
table[index].push_back(key);
}
void Hash::deleteItem(int key) {
int index = hashFunction(key);
list <int> :: iterator i;
for (i = table[index].begin(); i != table[index].end(); i++) {
if (*i == key) {
break;
}
}
if (i != table[index].end()) {
table[index].erase(i);
}
}
void Hash:: displayHash() {
for (int i = 0; i < BUCKET; i++) {
cout << i;
for (auto x : table[i]) {
cout << "-->" << x;
}
cout << endl;
}
}
// Driver program
int main()
{
// array that contains keys to be mapped
int a[] = {15, 11, 27, 8, 12};
int n = sizeof(a)/sizeof(a[0]);
// insert the keys into the hash table
Hash h(7); // 7 is count of buckets in
// hash table
for (int i = 0; i < n; i++)
h.insertItem(a[i]);
// delete 12 from hash table
h.deleteItem(12);
// display the Hash table
h.displayHash();
return 0;
}
关于此实现,我有两个令人困惑的点:
list<int> *table
:表应该是存储桶数组。右?list<int> *
应该是列表类型指针,对吧?它在这里是如何工作的?table = new list<int>[BUCKET]
: 我检查了许多列表相关
文档。 但没有找到[]
的工作原理?
list<int> *table
: table 应该是存储桶数组。右?list<int>*
应该是列表类型指针,对吧?它在这里是如何工作的?
在这个糟糕的代码中,table
是指向list<int>
的指针,但是当你有一个指向一个项目的指针并且碰巧知道那里有一个连续元素数组时,你可以像数组一样索引它,所以table[0]
与*table
相同,table[1]
将是内存中下一个list<int>
,在table[0]
之后,依此类推。
table = new list<int>[BUCKET]
: 我检查了许多列表相关文档。 但没有找到 [] 的工作原理?
这是创建list<int>
对象数组并将其地址保存在table
中的初始化,因此我们确实"碰巧知道"数组存在并且可以table
作为数组进行索引。 例如,在displayHash
函数中,您会看到for (auto x : table[i])
- 这意味着x
从存储桶i
list<int>
获取每个值,这是table[i]
。
代码还需要一个析构函数来delete[] table
,否则当Hash
对象的默认析构函数运行时,所有内存都将泄漏而不进行任何清理。
您还应该知道,它允许您插入同一密钥的多个副本 - 此功能的正确和完整实现是std::unordered_multiset
。
最低限度地清理它 - 无需采取后续步骤来使用模板以允许您将其用于其他类型的,添加迭代器等:
class Hash {
vector<list<int>> table_;
public:
Hash(size_t size) : table_{size} { }
void insert(int key) {
table_[bucket(key)].push_back(key);
}
void erase(int key) {
auto& bucket_list = table_[bucket(key)];
auto it = find(bucket_list.begin(), bucket_list.end(), key);
if (it != bucket_list.end())
bucket_list.erase(it);
}
int bucket(int key) const {
return hash(key) % table_.size();
}
static int hash(int key) {
return key;
}
// example usage: my_hash.display(std::cout);
void display(std::ostream& os) const {
for (size_t i = 0; i < table_.size_; ++i) {
os << '[' << i << ']';
for (auto x : table[i])
os << "-->" << x;
os << 'n';
}
}
// extensions ===================================
bool contains(int key) const {
auto& bucket_list = table_[bucket(key)];
auto it = find(bucket_list.begin(), bucket_list.end(), key);
return it != bucket_list.end();
}
// example usage:
// my_hash.visit([](auto key) { std::cout << key << 'n'; });
template <typename Functor)
void visit(Functor functor) const {
for (size_t i = 0; i < table_.size_; ++i)
for (auto x : table[i])
functor(x);
}
};
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 在C应用程序中运行C++(带有STL)函数
- 使用2个键的cpp-stl::优先级队列排序不正确
- 在STL容器中使用模板类
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 将stl字符串缩小到小于15个字符的容量
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查函数返回类型是否与STL容器类型值相同
- STL算法函数在多个一维容器上的使用
- 在STL - C++中按成绩对学生列表进行排序?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- λ可以适应STL吗?
- 为什么使用 NDK 不能存在不同的 stl 实现?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用 char 分隔符解析C++中的字符串,但将可重复的字符保留为每个解析的子字符串 (C++ STL) 中的分隔符
- 在C++中迭代 STL 集时出现奇怪的问题<CStudent>
- 如何在 C++17 STL 并行算法中处理调度?
- 在学习数据结构之前对STL有一个了解是好的吗?
- hashtable :如何理解这种基于STL中List的hashtable实现