说到哈希冲突,就必须谈到哈希函数了。
什么时候哈希函数
哈希冲突函数hv(i),用于在元素i发生哈希冲突时,将其映射至另一个内存位置。
什么是哈希冲突
哈希冲突即关键字不同的元素被映射到了同一个内存位置,包括由同义词冲突和非同义词冲突。
处理哈希冲突的方法很多,这里浅谈一下处理哈希冲突的闭散列方法:
线性探测
如下图所示
在上图中,这里key取8。
实现线性探测代码:
#pragma once
#include<string>
enum Status
{
EXIST,
EMPTY,
DELETE,
};
//如果是数据类型,直接返回数据,定位位置
template<class T>
struct DataType
{
long long operator()(const T&key)
{
return key;
}
};
//如果是字符串类型,求出字符串ASCII和,根据求出的和定位位置
template<class T>
struct StringType
{
long long operator()(const string&key)
{
long long size = 0;
for (size_t i = 0; i < key.size(); i++)
{
size = size + key[i];
}
return size;
}
};
//定义的哈希类
template<class T,template<class T> class HashFuncer=DataType>
//class HashFuncer = DataType<T>
class HashTable
{
public:
HashTable()
:_tables(NULL)
, _status(NULL)
, _size(0)
, _capacity(0)
{}
HashTable(const size_t size)
:_tables(new T[size])
, _status(new Status[size])
, _size(0)
, _capacity(size)
{
for (size_t i = 0; i < size; i++)
{
_status[i] = EMPTY;
}
}
HashTable(const HashTable<T,HashFuncer>&ht)
{
HashTable<T,HashFuncer> tmp(ht._capacity);
for (size_t i = 0; i < ht._capacity; i++)
{
if (ht._status[i] != EMPTY)
{
tmp._status[i] = ht._status[i];
tmp._tables[i] = ht._tables[i];
}
}
tmp._size = ht._size;
tmp._capacity = ht._capacity;
this->Swap(tmp);
}
~HashTable()
{
if (_tables)
{
delete[] _tables;
delete[] _status;
}
_size = 0;
_capacity = 0;
}
HashTable<T, HashFuncer>& operator=(const HashTable<T, HashFuncer> &ht)
{
if (_tables != ht._tables)
{
HashTable<T, HashFuncer> ht1(ht);
/*HashTable<T, HashFuncer> ht1(ht._capacity);
for (size_t i = 0; i < ht._capacity; i++)
{
if (ht._status[i] != EMPTY)
{
ht1._tables[i] = ht._tables[i];
ht1._status[i] = ht._status[i];
}
}
ht1._size = ht._size;*/
this->Swap(ht1);
}
return *this;
}
bool Insert(const T&key)
{
_CheckCapacity();
size_t index = _HashFunc(key);
while (_status[index] == EXIST)
{
if (_tables[index] == key)
{
return false;
}
++index;
if (index == _capacity)
{
index = 0;
}
}
_status[index] = EXIST;
_tables[index] = key;
_size++;
return true;
}
size_t Find(const T&key)
{
size_t index = _HashFunc(key);
while (_status[index] != EMPTY)
{
if (_tables[index] == key&&_status[index] != DELETE)
{
return index;
}
++index;
if (index == _capacity)
{
index = 0;
}
}
return -1;
}
bool Remove(const T&key)
{
int index = Find(key);
if (index != -1)
{
_status[index] = DELETE;
return true;
}
return false;
}
void _CheckCapacity()//载荷因子
{
if (_size * 10 >= _capacity * 7)
{
HashTable<T,HashFuncer> tmp(2 * _capacity+3);
for (size_t i = 0; i < _capacity; ++i)
{
if (_status[i] != EMPTY)
{
tmp.Insert(_tables[i]);
}
}
this->Swap(tmp);
}
}
void PrintTables()
{
for (size_t i = 0; i < _capacity; ++i)
{
if (_status[i] == EXIST)
{
printf("[%d]:E->", i);
cout << _tables[i];
}
else if (_status[i] == DELETE)
{
printf("[%d]:D->", i);
cout << _tables[i];
}
else if (_status[i] == EMPTY)
{
printf("[%d]:N->NONE", i);
}
cout << endl;
}
cout << endl;
}
void Swap(HashTable<T,HashFuncer> &ht)
{
swap(_tables, ht._tables);
swap(_status, ht._status);
swap(_size, ht._size);
swap(_capacity, ht._capacity);
}
size_t _HashFunc(const T&key)
{
HashFuncer<T> hf;
return hf(key)%_capacity;
}
protected:
T *_tables;
Status *_status;
size_t _size;
size_t _capacity;
};
转载于:https://blog.51cto.com/10794428/1784804