这段代码实现了一个简单的哈希表(HashTable
)类,使用链式法处理冲突。以下是对代码的逐步解释:
1. 头文件和命名空间
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <iostream>
: 包含标准输入输出流。#include <vector>
: 包含动态数组类std::vector
。#include <list>
: 包含双向链表类std::list
。#include <iterator>
: 提供迭代器功能,但在这个示例中并未直接使用。
2. HashTable 类定义
class HashTable {
public:
HashTable(size_t size) : table(size), num_elements(0), load_factor_threshold(0.75) {}
- 构造函数:接受一个大小参数,并初始化哈希表的基础数据结构:
table
: 使用给定大小创建一个包含链表的向量。num_elements
: 当前存储在哈希表中的元素数量,初始为0。load_factor_threshold
: 加载因子阈值,当存储的元素数量与表大小之比超过该值时,会触发扩容。
3. 插入操作
void insert(int key, int value) {
if ((double)num_elements / table.size() >= load_factor_threshold) {
resize(table.size() * 2);
}
size_t index = hashFunction(key);
for (auto& kv : table[index]) {
if (kv.first == key) {
kv.second = value;
return;
}
}
table[index].emplace_back(key, value);
num_elements++;
}
- 检查加载因子:如果当前元素数量与表大小之比超过设定阈值,则调用
resize()
方法将哈希表容量扩大一倍。 - 计算索引:通过哈希函数计算出插入位置的索引。
- 查找现有键:遍历对应链表,如果找到相同键则更新其值并返回。
- 插入新元素:如果没有找到现有键,使用
emplace_back()
方法将新的键值对插入到对应链表中,并增加元素计数。
4. 查找操作
bool find(int key, int& value) {
size_t index = hashFunction(key);
for (const auto& kv : table[index]) {
if (kv.first == key) {
value = kv.second;
return true;
}
}
return false;
}
- 查找特定键:根据提供的键计算索引,然后遍历对应链表。如果找到匹配的键,则通过引用参数返回其值并返回 true;否则返回 false。
5. 删除操作
void remove(int key) {
size_t index = hashFunction(key);
auto& cell = table[index];
for (auto it = cell.begin(); it != cell.end(); ++it) {
if (it->first == key) {
cell.erase(it);
num_elements--;
return;
}
}
}
- 删除特定键:计算索引后,遍历对应链表。如果找到匹配的键,使用迭代器从链表中删除它,并减少元素计数。
6. 哈希函数与扩容方法
private:
size_t hashFunction(int key) const {
return key % table.size();
}
void resize(size_t new_size) {
std::vector<std::list<std::pair<int, int>>> new_table(new_size);
for (const auto& cell : table) {
for (const auto& kv : cell) {
size_t new_index = kv.first % new_size;
new_table[new_index].emplace_back(kv.first, kv.second);
}
}
table = std::move(new_table);
}
哈希函数: 简单地使用取模运算来确定每个键的位置。
扩容方法: 创建一个新的更大的哈希表,然后将原有所有项重新映射到新位置,这样可以降低冲突率并提高性能。
7. 主程序示例
int main() {
HashTable ht(10);
ht.insert(1, 100);
ht.insert(11, 200);
ht.insert(21, 300);
int value;
if (ht.find(11, value)) { /* ... */ }
ht.remove(11);
if (ht.find(11, value)) { /* ... */ }
return 0;
}
这里创建了一个初始容量为10的哈希表示例,并执行了一些插入、查找和删除操作,以验证基本功能是否正常。程序最终输出有关所查询和删除的元素的信息。
总结
这个简单的哈希表示例展示了如何通过开放地址法处理冲突,以及如何管理内存和动态调整大小。虽然实现比较基础,但足以理解基本概念和操作。
内容由零声教学AI助手提供,问题来源于学员提问