本文参考了《数据结构与算法分析C++描述(第3版)》[美] Mark Weiss 著 张怀勇 等译 刘田 审校
使用二次探测法。
#include "stdafx.h"
#include<vector>
#include<iostream>
using namespace std;
#define EMPTY 0
#define EXIST 1
#define DELETED 2
template <typename T>
class hashtable
{
private:
vector<T> datatable;//储存元素的数组
vector<int> typetable;//储存键对应状态的数组
int realsize;//实际存的元素数量
int myhash(T x){//根据不同数据类型有不同的hash函数
return hash(x);
}
int hash(T x){
return(x % datatable.size());
}
public:
hashtable(int s = 11)//构造函数,默认初始键数为11
{
realsize = 0;
datatable.resize(s);
typetable.resize(s);
for(int i = 0;i < typetable.size();i++){
typetable.at(i) = EMPTY;
}
}
~hashtable()
{
makempty();
}
void makempty()
{
datatable.clear();
typetable.clear();
}
bool isactive(int key)
{
return(typetable.at(key) == EXIST);
}
int findpos(T x)//查找一个元素的路径,这里使用平方探测的方法
{
int index;
for(int i = 0 ;i < datatable.size(); i++)
{
index = (myhash(x)+i*i) % typetable.size();
int type_state = typetable.at(index);//kong表示此键所在位置没有存放元素
T value = datatable.at(index);
if (type_state == EMPTY)
{
break;
}
else if (type_state == EXIST)
{
if (value == x)
{
break;
}
}
else if (type_state == DELETED)
{
if (value == x)
{
break;
}
}
}
return index;
}
int findpos_for_insert(T x)//插入的时候遇到empty或deleted都可以插入
{
int index;
for(int i = 0 ;i < datatable.size(); i++)
{
index = (myhash(x) + i*i) % typetable.size();
int type_state = typetable.at(index);//kong表示此键所在位置没有存放元素
if (type_state == EMPTY)
{
break;
}
else if (type_state == EXIST)
{
}
else if (type_state == DELETED)
{
break;
}
}
return index;
}
bool contain(T x)//查找x是否存在于哈希表中
{
return isactive(findpos(x));
}
bool insert(T x)//插入一个元素
{
if (contain(x))
{
return false;
}
int p = findpos_for_insert(x);
datatable.at(p) = x;
typetable.at(p) = EXIST;
realsize++;
if(realsize >= datatable.size()/2)
rehash();
return true;
}
bool remove(T x)//删除一个元素
{
int p=findpos(x);
if (!isactive(p))
return false;
typetable.at(p) = DELETED;//懒惰删除
realsize--;
return true;
}
void print()
{
cout << "散列表内容:" << endl;
for(int i = 0;i < datatable.size();i++){
cout << "键" << i << ":" ;
if(typetable.at(i) == EXIST)
cout << datatable.at(i) << endl;
else
cout << "empty" << endl;
}
cout << endl;
}
void rehash()//再散列
{
vector<T> olddatatable=datatable;
vector<int> oldtypetable=typetable;
datatable.resize(datatable.size()*2+1);
typetable.resize(typetable.size()*2+1);
for(int i = 0;i < typetable.size();i++){
typetable.at(i) = 0;
}
realsize = 0;
for(int j = 0;j < olddatatable.size();j++){
if(oldtypetable.at(j) == EXIST)
insert(olddatatable.at(j));
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
hashtable<int>hs;
for(int i = 0;i <= 1;i++)
hs.insert(i);
hs.print();
hs.insert(11);
hs.print();
hs.remove(0);
hs.print();
cout << hs.contain(11);
return 0;
}
部分运行结果截图: