#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
template <typename HashedObj>
class HashTable
{
public:
explicit HashTable(int size=101)
:theSize(nextPrime(size)),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=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;
}
void print()
{
for(auto HashEntry:array)
if(HashEntry.info==ACTIVE)
cout<<HashEntry.element<<endl;
}
enum EntryType{ACTIVE,EMPTY,DELETED};
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(e),info(i)
{ }
};
vector<HashEntry> array;
int currentSize;
int theSize;
bool isActive(int currentPos) const
{
return array[currentPos].info==ACTIVE;
}
int findPos(const HashedObj &x) const
{
int offset=1;
int currentPos=myhash(x);
while(array[currentPos].info!=EMPTY&&
array[currentPos].element!=x)
{
currentPos+=offset;
offset+=2;
if(currentPos>=array.size())
currentPos-=array.size();
}
return currentPos;
}
void rehash()
{
vector<HashEntry> oldArray=array;
array.resize(nextPrime(2*oldArray.size()));
for(auto &entry:array)
entry.info=EMPTY;
currentSize=0;
for(auto &entry:oldArray)
if(entry.info==ACTIVE)
insert(std::move(entry.element));
}
int myhash(const HashedObj &x) const
{
int hashVal=0;
for(auto &c:x)
hashVal=131*hashVal+c;
hashVal%=array.size();
if(hashVal<0)
hashVal+=theSize;
return hashVal;
}
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;
}
};
int main()
{
HashTable<string> hash;
hash.insert("this");
hash.print();
}
平方探测哈希表
最新推荐文章于 2021-11-24 17:31:19 发布