代码
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
class HashTable {
public:
HashTable(int size = primes_[0], double loadFactor=0.75)
: useBucketNum_(0)
, loadFactor_(loadFactor)
, primeIdx_(0) {
if (size != primes_[0]) {
for (; primeIdx_ < PRIME_SIZE; primeIdx_++) {
if (primes_[primeIdx_] >= size) {
break;
}
}
if (primeIdx_ == PRIME_SIZE) {
primeIdx_--;
}
}
table_.resize(primes_[primeIdx_]);
}
public:
void insert(int key) {
double factor = useBucketNum_ * 1.0 / table_.size();
std::cout << "factor: " << factor << std::endl;
if (factor > loadFactor_) {
expand();
}
int idx = key % table_.size();
if (table_[idx].empty()) {
useBucketNum_++;
table_[idx].emplace_front(key);
} else {
auto it = ::find(table_[idx].begin(), table_[idx].end(), key);
if (it == table_[idx].end()) {
table_[idx].emplace_front(key);
}
}
}
void erase(int key) {
int idx = key % table_.size();
auto it = ::find(table_[idx].begin(), table_[idx].end(), key);
if (it != table_[idx].end()) {
table_[idx].erase(it);
if (table_[idx].empty()) {
useBucketNum_--;
}
}
}
bool find(int key) {
int idx = key % table_.size();
auto it = ::find(table_[idx].begin(), table_[idx].end(), key);
if (it != table_[idx].end()) {
return true;
}
return false;
}
private:
void expand() {
if (primeIdx_ + 1 == PRIME_SIZE) {
throw "hashtable can not expand anymore";
}
primeIdx_++;
useBucketNum_ = 0;
vector<list<int>> oldTable;
table_.swap(oldTable);
table_.resize(primes_[primeIdx_]);
for (auto list : oldTable) {
for (auto key : list) {
int idx = key % table_.size();
if (table_[idx].empty()) {
useBucketNum_++;
}
table_[idx].emplace_front(key);
}
}
}
private:
vector<list<int>> table_;
int useBucketNum_;
double loadFactor_;
static const int PRIME_SIZE = 10;
static int primes_[PRIME_SIZE];
int primeIdx_;
};
int HashTable::primes_[PRIME_SIZE] = {3, 7, 23, 47, 97, 251, 443, 911, 1471, 42773};
测试
int main() {
HashTable htable;
htable.insert(21);
htable.insert(32);
htable.insert(14);
htable.insert(15);
htable.insert(19);
htable.insert(78);
htable.insert(678);
std::cout << "查找结果:" << htable.find(14) << std::endl;
htable.erase(14);
std::cout << "查找结果:" << htable.find(14) << std::endl;
return 0;
}
➜ build git:(main) ✗ ./HashTable
factor: 0
factor: 0.333333
factor: 0.666667
factor: 0.666667
factor: 0.666667
factor: 1
factor: 0.571429
查找结果:1
查找结果:0