HashTable的实现测试

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数值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值