/*************************************************************************
> File Name: HashTable2.h
> Author:keson
> Mail:keson@bupt.edu.cn
> Created Time: 2014年11月26日 星期三 11时05分23秒
************************************************************************/
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class hashValue
{
public:
size_t operator()(const string &key)
{
size_t hashVal=0;
for(auto c:key)
hashVal=37*hashVal+c;
return hashVal;
}
};
template<typename HashedObj>
class HashTable2
{
public:
explicit HashTable2(int size=101):array(nextPrime(size))
{makeEmpty();}
bool contains(const HashedObj &x) const
{
return isActive(findPos(x));
}
void makeEmpty()
{
currentSize=0;
for(auto &entry:array)
entry.info=EMPTY;
}
bool insert(const HashedObj &x)
{
int currentPos=findPos(x);
if(isActive(currentPos))
return false;
array[currentPos].element=x;
array[currentPos].info=ACTIVE;
if(++currentSize>array.size()/2)
rehash();
return true;
}
bool insert(HashedObj &&x)
{
int currentPos=findPos(x);
if(isActive(currentPos))
return false;
array[currentPos].element=std::move(x);
array[currentPos].info=ACTIVE;
if(++currentSize>array.size()/2)
rehash();
return true;
}
bool remove(const HashedObj &x)
{
int currentPos=findPos(x);
if(!isActive(currentPos))
return false;
array[currentPos].info=DELETED;
return true;
}
enum EntryType{ACTIVE,EMPTY,DELETED};
void print()
{
for(auto entry:array)
if(entry.info==ACTIVE)
cout<<entry.element<<endl;
}
private:
struct HashEntry
{
HashedObj element;
EntryType info;
HashEntry(const HashedObj &e=HashedObj{},EntryType i=EMPTY)
:element{e},info{i} {}
HashEntry(HashedObj &&e,EntryType i=EMPTY)
:element{std::move(e)},info{i} {}
};
vector<HashEntry> array;
int currentSize;
bool isActive(int currentPos) const
{
return array[currentPos].info==ACTIVE;
}
int findPos(const HashedObj &x) const
{
int offset=1;
int currentPos=myhash(x);
//the order can't change.
while(array[currentPos].info!=EMPTY&&
array[currentPos].element!=x)
{
currentPos+=offset; //Compute ith probe
offset+=2;
if(currentPos>=array.size())
currentPos-=array.size();
}
return currentPos;
}
bool isPrime(int num)
{
if (num == 2 || num == 3)
{
return true;
}
if (num % 6 != 1 && num % 6 != 5)
{
return false;
}
for (int i = 5; i*i <= num; i += 6)
{
if (num % i == 0 || num % (i+2) == 0)
{
return false;
}
}
return true;
}
int nextPrime(int n)
{
bool state=isPrime(n);
while(!state)
{
state=isPrime(++n);
}
return n;
}
void rehash()
{
vector<HashEntry> oldArray=array;
//Create new double-sized,empty table
array.resize(nextPrime(2*oldArray.size()));
for(int j=0;j<array.size();j++)
array[j].info=EMPTY;
currentSize=0;
for(int i=0;i<oldArray.size();i++)
if(oldArray[i].info==ACTIVE)
insert(oldArray[i].element);
}
size_t myhash(const HashedObj &x) const
{
static hashValue hf;
return hf(x)%array.size();
}
};
int main()
{
HashTable2<string> a;
a.insert("Hello");
a.print();
}
hash表-平方探测,数据结构与算法分析第四版的(增加了上文的nextPrime)
最新推荐文章于 2023-11-28 16:10:57 发布