0
点赞
收藏
分享

微信扫一扫

HashTable

f12b11374cba 2022-09-02 阅读 61



#pragma once 

//直接定址法:利用公式
enum Status//状态
{
EXIST,//存在
DELETE,//删除
EMPTY,//空
};

template<class K>
class HashTable
{
public:
HashTable()//无参
:_tables(0)
, _status(0)
, _size(0)
, _capacity(0)
{}

HashTable(size_t size)
:_tables(new K[size])//开辟K类型size个数据
, _status(new Status[size])//
, _size(0)
, _capacity(size)
{//初始化
for (size_t i = 0; i < _capacity; i++)
{
_tables[i] =_status[i] = EMPTY;
}
}

~HashTable()
{
if (_tables)
{
delete[] _tables;
delete[] _status;
_tables = NULL;
_status = NULL;
}
_size = 0;
_capacity = 0;
}

//Insert
bool Insert(const K& key)
{
//1.容量的问题 2.检查数据重复 3.插入
_CheckCapacity();
size_t index = _HashFunc(key);//直接定值法找到下标
while (_status[index] == EXIST)//如果状态是存在,
{
if (_status[index] == key)//和key相同,说明已经存在相同的数据
{
return false;
}
++index;//如果计算的位置已有数据,index后移
if (index == _capacity)
{
index = 0; //如果满了,就重新置零
}
}
//程序走到这里,就找到合适的位置,然后插入
_tables[index] = key;
_status[index] = EXIST;//将数据状态改为存在EXIST
_size++;
return true;
}

//Find
int Find(const K& key)
{
size_t index = _HashFunc(key);//通过key找到index
while (_status[index] != EMPTY) //exist empty delete
{
if (_status[index] == EXIST&&_tables[index] == key)
{//因为是懒汉式删除法,只改变了状态,并没有删除数据,所以必须
//通过_status来查找
return index; //返回下标
}
index++;
}
return -1;
}

bool Remove(const K& key)
{
int index = Find(key);
if (index == -1)
{//返回-1说明不存在
return false;
}
else
{//直接改变_status的状态---懒汉式
_status[index] = DELETE; //懒汉式删除,只修改状态,不更改数据
//--_size;
return true;
}
}

void PrintHashTable()
{
for (size_t i = 0; i < _capacity; i++)
{
if (_status[i] == EXIST)
{
printf("[%d];E->%d", i, _tables[i]);
cout << endl;
}
else if (_status[i] == DELETE)
{
printf("[%d];D->%d", i, _tables[i]);
cout << endl;
}
else
{
printf("[%d];N", i);
cout << endl;
}
}
}

protected:
//找映射在hash上的位置
size_t _HashFunc(const K& key)
{
return key %_capacity; //整数就直接模容量
}
void _CheckCapacity()
{
if (10 * _size >= 7 * _capacity) //考虑载荷因子的问题,如果超过0.7 就增容
{
HashTable<K > tmp(2 * _capacity);
for (size_t i = 0; i < _capacity; ++i)
{
if (_status[i] == EXIST)//状态为删除时不用管
{
tmp.Insert(_tables[i]);
}
}
this->Swap(tmp);//冲突改变,相对位置改变
}
}

void Swap(HashTable <K>& tmp)
{
swap(_tables, tmp._tables);
swap(_status, tmp._status);
swap(_size, tmp._size);
swap(_capacity, tmp._capacity);
}

protected:
K* _tables;//表
Status* _status;//状态
size_t _size;//size
size_t _capacity;//容量
};

void Test1()
{
HashTable<int > h1(10);
h1.Insert(1);
h1.Insert(2);
h1.Insert(3);
h1.Insert(4);
h1.Insert(5);
h1.Insert(6);
h1.Insert(7);
h1.Insert(8);

cout << h1.Find(1) << endl;
cout << h1.Find(2) << endl;
cout << h1.Find(3) << endl;
cout << h1.Find(4) << endl;
cout << h1.Find(5) << endl;
cout << h1.Find(6) << endl;
cout << h1.Find(7) << endl;
cout << h1.Find(8) << endl;

}

void Test2()
{
HashTable<int > h1(10);
h1.Insert(1);
h1.Insert(2);
h1.Insert(3);
h1.Insert(4);
h1.Insert(5);
h1.Insert(6);
h1.Insert(7);
h1.Insert(8);

h1.Remove(1);
h1.Remove(2);
h1.Remove(3);
h1.Remove(4);
h1.Remove(5);
h1.Remove(8);

cout << h1.Find(1) << endl;
cout << h1.Find(2) << endl;
cout << h1.Find(3) << endl;
cout << h1.Find(4) << endl;
cout << h1.Find(5) << endl;
cout << h1.Find(6) << endl;
cout << h1.Find(7) << endl;
cout << h1.Find(8) << endl;
h1.PrintHashTable();

}



举报

相关推荐

0 条评论