hash map

class hash_map {
  hash_map() {set_load(); v.reserve(max_load*b.size());}
  // 表“太满”(如 75% 满)时性能会恶化
  void set_load(float m=0.7, float g=1.6) {max_load=m; grow=g;}

  // 查找
  mapped_type& operator[] (const key_type& k) {
    // 先计算散列值,查找表索引
    size_type i = hash(k) % b.size();
    // 找到之后遍历散列链匹配
    for(Entry* p=b[i]; p; p=p->next) {
      if(eq(k, p->key)) { // 找到则插入表
        if(p->erased) {
          p->erased = false;
          no_of_erased--;
          return p->val = default_value;
        }
        return p->val;
      }
    }
    // 找不到则插入散列表
    // 若表已经“满”了,增大存储
    if(size_tye(b.size() * max_load) <= v.size()) {
      resize(b.size() * grow);
      return operator[](k);
    }
    // 插入元素
    v.push_back(Entry(k, default_value, b[i]));
    b[i] = &v.back();
    return b[i]->val;
  }

  // 调整散列表大小
  void resize(size_type s) {
    // 计算 erased 元素数目,同时从存储中删除对应元素
    size_type i = v.size()
    while(no_of_erased) {
      if(v[--i].erased) {
        v.erase(&v[i]);
        --no_of_erased;
      }
    }
    // 如果 b.size() >= s,返回
    if(s <= b.size()) return;
    // 如果 b.size() < s,增大 b,b 全部清 0,重新计算
    b.resize(s);
    fill(b.begin(), b.end(), 0);
    // 重新分配底层存储
    v.reserve(s * max_load);
    // 重新计算元素散列值
    for(size_type i=0; i<v.size(); i++) {
      size_type ii = hash(v[i].key) % b.size();
      v[i].next = b[ii];
      b[ii] = &v[i];
    }
  }

private:
  struct Entry {
    key_type key;
    mapped_type val;
    bool erased;
    Entry* next;          // 散列链
  };
  vector<Entry> v;        // 实际存储
  vector<Entry*> b;       // 散列表,保存实际存储的指针

  float max_load;         // 保持 v.size() <= b.size()*max_load
  float grow;             // 接近太满时自动改变大小 resize(bucket_count() * grow)
  size_type no_of_erased; // erased 元素项的数目
  Hasher hash;            // 散列函数
  key_equal eq;           // 相等判断

  const T default_value;  // entry 默认值
};

相关