可扩散列
相当于一个根节点可以持续扩容的高度为1的B+树。
线性探测
f(i)=i,但是对应一次聚集
平方探测
f(i)=i²,但是对应二次聚集
双散列
f(i)=i*hash2(i),第二个函数选择很重要。
再散列
用平方探测的方式寻找位置。当表用了一半、插入失败、到达某一个装填因子时候扩容散列表。
使用列表实现的hashtable
使用了STL中的vector、list
template <typename T>
class HashTable
{
public:
explicit HashTable (int size = 101);
bool contains ( const T & t) const
{
return find(lists[myhash(t)].begin(), lists[myhash(t)].end(), t) == lists[myhash(t)].end();
}
void makeEmpty()
{
for(int i = 0; i < lists.size(); ++i)
lists[i].clear();
}
bool insert( const T & t)
{
if(contains(t))
return false;
list<T> & l = lists[myhash(t)];
l.push_back(t);
if( ++currentSize > lists.size())
rehash();
return true;
}
bool remove( const T & t)
{
if( !contains(t))
return false;
list<T> % l = lists[myhash(t)];
list<T>::iterator itr = find(l.begin(), l.end(), t);
l.erase(itr);
return true;
}
private:
vector< list<T> > lists;//有的编译器对>>识别为运算符,最好飞开
int currentSize;
void rehash()
{
vector<list<T> > oldarray = lists;
lists.resize( nextPrime(2 * lists.size());
//nextPrime(x)取得比x大的最小的素数
for(int i = 0; i < lists.size(); ++i)
lists[i].resize(0);
for(int i = 0; i < oldarray.size(); ++i)
if(oldarray[i].size() != 0)
{
for(list<T>::iterator itr = oldarray][i].begin(); itr != oldarray][i].end; ++itr)
insert(*itr);
}
}
int myhash( const T & t) const
{
int hashVal = hash(t.getHahsVal()); // T类型的数据都应该有getHashVal()这个接口
hashVal &= lists.size();
if(hashVal < 0)
hashVal += lists.size();
return hashVal;
}
};
int hash(string s)
{
int hashVal = 0;
for(int i = 0; i <s.size(); ++i)
hashVal = 37 * hashVal + s[i];
return hashVal;
}