ZBLOG

#include #include #include #include class HashTable { public: HashTable(size_t size) : table(size), num_elements(0), load_factor_threshold(0.75) {} void insert(int key, int value) { if ((doub...

这段代码实现了一个简单的哈希表(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助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22654

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?