---------来自STL源码剖析
#include <iostream>
#include <vector>
#include <cstdio>
#include <list>
using namespace std;
const int hash_prime_num = 15;
const unsigned int _stl_prime[] = {
2, 5, 11, 23, 53,
97, 193, 389, 769, 1543,
3079, 6151, 12289, 24593, 49157
};//此处定义出15个素数,以便于用开链法建立哈希表
template<class T, class H, class E, class type_value>
//四个模板类型,分为代表集合元素类型,哈希仿函数,相等判定仿函数,底层容器实现方式(开链法链的实现方式)
struct Hash_set{
typedef typename vector<type_value>::iterator first_it;
typedef typename type_value::iterator second_it;
typedef typename vector<type_value>::const_iterator first_ct;
typedef typename type_value::const_iterator second_ct;
typedef vector<type_value>* pointer;
typedef T type;
size_t count, table_size;//前者是集合元素数目,后者是哈希表大小
vector<type_value> v;//哈希表,用vector实现
H hash;//哈希仿函数
E equal;//相等判定仿函数
size_t find_prime(int num){//查找下一个更大的素数
for(int i = 0; i < hash_prime_num; i++){
if(_stl_prime[i] > num) return _stl_prime[i];
}
}
bool add(const T& data){//把一个元素加入哈希表,元素不可以重复
size_t index = hash(data) % table_size;
type_value &buf = v[index];
for(second_it it = buf.begin(); it != buf.end(); ++it)
if(equal(data, *it)) return false;
v[index].push_back(data);
return true;
}
public:
struct iterator{//依旧是一个很简陋的迭代器,只重载了前++运算符
first_it itx;
second_it ity;
pointer v;
iterator():itx(first_it()), ity(second_it()), v(NULL){}
iterator(const iterator& buf){itx = buf.itx, ity = buf.ity, v = buf.v;}
iterator(const first_it& _x, const second_it& _y, pointer _v):itx(_x), ity(_y), v(_v){}
T& operator*(){ return *ity;}
bool operator ==(const iterator& R){return itx == R.itx && ity == R.ity;}
bool operator != (const iterator& R){return !(itx == R.itx && ity == R.ity);}
iterator& operator ++(){
if(++ity != itx->end()) { return *this;}
for(++itx; itx != v->end(); ++itx) if(itx->size()){
ity = itx->begin();
return *this;
}
ity = second_it();
return *this;
}
};
iterator begin(){//返回首迭代器
for(first_it it = v.begin(); it != v.end(); ++it) if(it->size())
return iterator(it, it->begin(), &v);
}
iterator begin()const{
for(first_ct it = v.begin(); it != v.end(); ++it) if(it->size())
return iterator(it, it->begin(), &v);
}
iterator end(){ return iterator(v.end(), second_it(), NULL);}//返回最后一个元素的下一个迭代器
iterator end()const{ return iterator(v.end(), second_ct(), NULL);}
Hash_set(){table_size = 2, count = 0, v.resize(table_size);}
size_t size()const{ return count;}//集合元素数目
size_t hash_size()const{ return table_size;}// 是哈希表大小
Hash_set& operator = (const Hash_set& R){v = R.v;}//重载赋值运算符
void insert(const T& data){//插入一个元素
if(count == table_size/2){
type_value buf;
for(first_it itx = v.begin(); itx != v.end(); ++itx)
for(second_it ity = itx->begin(); ity != itx->end(); ++ity)
buf.push_back(*ity);
table_size = find_prime(table_size);
v.clear();
v.resize(table_size);
for(second_it it = buf.begin(); it != buf.end(); ++it) add(*it);
}
count += add(data);
}
bool find(const T& data){//查找一个元素是否存在
size_t index = (hash(data)) % table_size;
type_value &buf = v[index];
for( second_it it = buf.begin(); it != buf.end(); ++it)
if(equal(data, *it)) return true;
return false;
}
bool find(const T& data)const{
size_t index = (hash(data)) % table_size;
type_value &buf = v[index];
for(second_ct it = buf.begin(); it != buf.end(); ++it)
if(equal(data, *it)) return true;
return false;
}
void erase(const T& data){//删除一个元素
size_t index = (hash(data)) % table_size;
type_value &buf = v[index];
for(second_it it = buf.begin(); it != buf.end(); ++it)
if(equal(data, *it)){
buf.erase(it);
break;
}
}
};
struct hasher{
size_t operator()(int x)const{
return x;
}
};
struct equaler{
bool operator()(int a, int b)const{
return a == b;
}
};
int main(int argc, char** argv) {
Hash_set<int, hasher, equaler, list<int> > st, R;
for(int i = 0; i < 10; i++) st.insert(i*2-3);
for(int i = 0; i < 10; i++) cout << st.find(i) << " ";
puts("");
for(Hash_set<int, hasher, equaler, list<int> >::iterator it = st.begin(); it != st.end(); ++it){
cout << *it << " " << endl;
}
puts("----------------");
R = st;
for(Hash_set<int, hasher, equaler, list<int> >::iterator it = R.begin(); it != R.end(); ++it){
cout << *it << " " << endl;
}
cout << st.size() << " " << st.hash_size() << endl;
return 0;
}