采用分离链接法处理冲突,
即当产生冲突时,将以链表的形式将新元素插入原来的元素之后
/***********************************************
> Filename: HashTable.cpp
> Author: Pyt
> Create: 2017-08-19 10:00:00
************************************************/
/***分离链接法****/
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
/**string类型获得hash值***/
int mhash(const string &t)
{
int sum = 0;
for(int i=0; i<t.size(); i++)
{
sum = sum*37+t[i];
}
return sum;
}
/***重载int包含char double隐式转换为int****/
int mhash(const int &t)
{
return t;
}
template<typename T>
class HashTable{
public:
explicit HashTable(int size = 101);
bool contains(const T &t) const;
void clear();
bool insert(const T &t);
bool remove(const T &t);
private:
vector<list<T> > theList;
int cursize;
int myhash(const T &t) const;
void rehash();
int nextPrime(const int &x);
bool isPrime(const int &x);
};
/**构造函数****/
template<typename T>
HashTable<T>::HashTable(int size)
: theList(size), cursize(0)
{
}
/***是否包含某值***/
template<typename T>
bool HashTable<T>::contains(const T &t) const
{
const list<T> &obj = theList[myhash(t)];
return find(obj.begin(), obj.end(), t) != obj.end();
}
/****清空表****/
template<typename T>
void HashTable<T>::clear()
{
for(int i=0; i<theList.size(); i++)
theList[i].clear();
}
/***删除某元素****/
template<typename T>
bool HashTable<T>::remove(const T &t)
{
int index = myhash(t);
typename list<T>::iterator it = find(theList[index].begin(), theList[index].end(), t);
if(it == theList[index].end())
return false;
theList[index].erase(it);
cursize--;
return true;
}
/***插入元素****/
template<typename T>
bool HashTable<T>::insert(const T &t)
{
int index = myhash(t);
if(contains(t))
return false;
theList[index].push_back(t);
if(++cursize > theList.size())
rehash();
return true;
}
/***获得插入index***/
template<typename T>
int HashTable<T>::myhash(const T &t) const
{
int hashVal = mhash(t);
hashVal %= theList.size();
if(hashVal < 0)
hashVal += theList.size();
return hashVal;
}
/****重建hash表用于扩大size****/
template<typename T>
void HashTable<T>::rehash()
{
vector<list<T> > old = theList;
theList.resize(nextPrime(theList.size()*2));
clear();
cursize = 0;
for(int i=0; i<old.size(); i++)
{
for(typename list<T>::iterator it=old[i].begin(); it!=old[i].end(); it++)
{
insert(*it);
}
}
}
/***下一个素数****/
template<typename T>
int HashTable<T>::nextPrime(const int &x)
{
for(int i=x+1; i++; )
if(isPrime(i))
return i;
}
/***是否位素数****/
template<typename T>
bool HashTable<T>::isPrime(const int &x)
{
for(int i=2; i<=sqrt(x); i++)
{
if(x%i == 0)
return false;
}
return true;
}
int main()
{
HashTable<string> ha;
string a;
ha.insert("xiaomng");
ha.insert("xiaozhang");
ha.insert("xiaoli");
ha.insert("xiaoming");
cout << ha.insert("xiaoli") << endl;
cout << ha.contains("xiaoli") << endl;
ha.remove("xiaoli");
cout << ha.contains("xiaoli") << endl;
HashTable<double> mm;
mm.insert(1.234);
return 0;
}