#include <iostream>
#include <vector>
using namespace std;
bool isPrime(int x)
{
for(int i = 2; i * i <= x; ++i)
{
if(x % i == 0)
return false;
}
return true;
}
int nextprime(int x)
{
for(;;++x)
{
if(isPrime(x))
return x;
}
}
template<class HashedObj>
class HashTable
{
public:
explicit HashTable(int size = 101);
bool contains(const HashedObj& x) const;
void makeEmpty();
bool insert(const HashedObj& x);
bool remove(const HashedObj& x);
enum EntryType{ACTIVE, EMPTY, DELETED};
void printhash() const;
private:
struct HashEnty
{
HashedObj element;
EntryType info;
HashEnty(const HashedObj &e = HashedObj(), EntryType i = EMPTY) :
element(e), info(i){}
};
vector<HashEnty> array;
int currentSize;
bool isActive(int currentPos) const;
int findPos(const HashedObj& x) const;
void rehash();
int myhash(const HashedObj& x) const;
int hash(const int& x) const;
int hash(const string& x) const;
};
template<class HashedObj>
HashTable<HashedObj>::HashTable(int size) : array(nextprime(size))
{
makeEmpty();
}
template<class HashedObj>
bool HashTable<HashedObj>::contains(const HashedObj& x) const
{
return isActive(findPos(x));
}
template<class HashedObj>
void HashTable<HashedObj>::makeEmpty()
{
currentSize = 0;
for(size_t i = 0; i < array.size(); ++i)
array[i].info = EMPTY;
}
template<class HashedObj>
bool HashTable<HashedObj>::insert(const HashedObj& x)
{
int currentPos = findPos(x);
if(isActive(currentPos))
return false;
array[currentPos] = HashEnty(x, ACTIVE);
if(++currentSize > array.size() / 2)
rehash();
return true;
}
template<class HashedObj>
bool HashTable<HashedObj>::remove(const HashedObj& x)
{
int currentPos = findPos(x);
if(!isActive(currentPos))
return false;
array[currentPos].info = DELETED;
return true;
}
template<class HashedObj>
bool HashTable<HashedObj>::isActive(int currentPos) const
{
return array[currentPos].info == ACTIVE;
}
template<class HashedObj>
int HashTable<HashedObj>::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;
}
template<class HashedObj>
void HashTable<HashedObj>::rehash()
{
vector<HashEnty> oldArray = array;
array.resize(nextprime(2 * oldArray.size()));
for(size_t i = 0; i < array.size(); ++i)
array[i].info = EMPTY;
currentSize = 0;
for(size_t i = 0; i < oldArray.size(); ++i)
if(oldArray[i].info == ACTIVE)
insert(oldArray[i].element);
}
template<class HashedObj>
int HashTable<HashedObj>::myhash(const HashedObj& x) const
{
int cnt = 0;
int hashVal = hash(x);
while(isActive(hashVal))
hashVal = (hash(x) + (++cnt)) % array.size();
return hashVal;
}
template<>
int HashTable<int>::hash(const int& x) const
{
int hashVal = x % array.size();
if(hashVal < 0)
hashVal += array.size();
return hashVal;
}
template<>
int HashTable<string>::hash(const string& x) const
{
int hashVal = 0;
for(size_t i = 0; i < x.length(); ++i)
hashVal = 37 * hashVal + x[i];
hashVal %= array.size();
if(hashVal < 0)
hashVal += array.size();
return hashVal;
}
template<class HashedObj>
void HashTable<HashedObj>::printhash() const
{
for(size_t i = 0; i != array.size(); ++i)
cout << array[i].element << " ";
}
int main()
{
return 0;
}
数据结构hashtable C++实现 非链式
最新推荐文章于 2023-07-05 00:20:42 发布