HashTable的实现测试

来源:互联网 发布:成都华为软件工厂 编辑:程序博客网 时间:2024/05/22 06:19

1)冲突解决方式,通过链表解决

2)slot数组中是否保存数据的问题,这个是一个容易让人困惑的问题,解决方案是slot不是HashNode的数组,而是一组指向HashNode的指针,因此slot数组中肯定不会保存数据

3)slot大小的选择,在HashTable的构造函数中设定大小,但hash函数使用了乘法策略,因此需要找到一个2^p>用户给的size的p,以2^p作为size,但存在这样的情况,如果用户给定大小size=33,实际的大小为64,最多是用户给定大小的2倍。

4)哈希函数使用乘法策略计算

5)Find函数返回的时Iterator,而不是ValueType类型的数据,主要是当Find失败时,如果返回ValueType类型的数据,不知道应该返回什么数据,不方
便用户进行判断,而参考std::map的实现,返回一个Itertor则要方便的多

6)重载了[]操作符,可以同时满足检索、插入和赋值

具体代码如下:

#include <stdio.h>#include <string>template<typename KeyType, typename ValueType>class HashNode {public:  HashNode() : next_(NULL) {}  HashNode(const KeyType& key, const ValueType& value) : key_(key), value_(value), next_(NULL) {}  KeyType key_;  ValueType value_;  HashNode<KeyType, ValueType>* next_;};template<typename KeyType, typename ValueType>class HashMap {public:  class Iterator {  public:    Iterator(HashMap* hash_map, int offset, HashNode<KeyType, ValueType>* current) : hash_map_(hash_map), offset_(offset), current_(current) {      if (!current_) {while (offset_ < hash_map_->slots_size_ && !hash_map->slots_[offset_]) {  offset_++;}current_ = hash_map->slots_[offset_];      }    }    KeyType& First() {      if (current_) {return current_->key_;      }    }    ValueType& Second() {      if (current_) {return current_->value_;      }    }    bool operator!=(const Iterator& right) {      return !((offset_ == right.offset_) && (current_ == right.current_));    }  private:    HashMap* hash_map_;    int offset_;    HashNode<KeyType, ValueType>* current_;  };  HashMap() {    HashMap(100);  }  HashMap(size_t size) {    slots_size_ = 1;    slots_bits_ = 0;    while ((slots_size_ <<= 1) <= size) {      slots_bits_++;    }    slots_ = new HashNode<KeyType, ValueType>*[slots_size_];    for (int i = 0; i < slots_size_; ++i) {      slots_[i] = NULL;    }    printf("slot_size:%d \n", slots_size_);  }  Iterator Find(const KeyType& key) {    unsigned int code = HashFun(key);    HashNode<KeyType, ValueType>* current = slots_[code];    while (current) {      if (current->key_ == key) {return Iterator(this, code, current);      }      current = current->next_;    }        return Iterator(this, slots_size_, NULL);  }  Iterator End() {    return Iterator(this, slots_size_, NULL);  }  ValueType& operator[](KeyType key) {    Iterator it = Find(key);    if (it != End()) {      return it.Second();    }    unsigned int code = HashFun(key);    ValueType value;    HashNode<KeyType, ValueType>* slot = new HashNode<KeyType, ValueType>(key, value);    slot->next_ = slots_[code];    slots_[code] = slot;    return slot->value_;  }private:  unsigned int HashFun(unsigned int key) {    const int fibonacci = 2654435769;    unsigned int code = (key * fibonacci) >> (32 - slots_bits_);    //    printf("hashcode:%d  %d\n", code, 32 - slots_bits_);    return code; }  HashNode<KeyType, ValueType>** slots_;  int slots_size_;  int slots_bits_;};std::string Itoa(int value, int radix, std::string* s) {  (*s) = "";  static char character[] = "0123456789ABCDEF";    if (value < 0) {    (*s) = "-";    value *= -1;  }  do {    (*s) += character[value % radix];  } while ((value /= radix) >0);  int start = 0;  int end = (*s).size() - 1;  if ((*s).size() >0 && (*s)[0] == '-') {    start = 1;  }  char tmp;  while (start < end) {    tmp = (*s)[start];    (*s)[start] = (*s)[end];    (*s)[end] = tmp;    start++;    end--;  }  return *s;}int main(int argc, char** argv) {  HashMap<int,std::string> hash_table(1000000);  const int kKeySize = 10000;  std::string s;  for (int i = 0; i < kKeySize; ++i) {    Itoa(i, 10, &s);    hash_table[i] = s;  }  for(int i = 0; i < kKeySize;  ++i) {    printf("%s\n", hash_table[i].c_str());  }}

还没有解决的问题是:目前key的类型只能是int,需要把给定类型转换成int数值。

原创粉丝点击