思路分析:
1.哈希表定义 ----成员定义(private):存储方式(哈希节点的数组)、元素空间的大小、哈希表构造函数
2.哈希表存入的数据类型: 哈希节点:哈希函数需要知道键值,因此键值数据设置成KV函数,同时哈希删除为假删除,因此需要定义状态
3.哈希表的插入(插入哈希节点)
3.1 检查容量
载荷因子大于设置的0.7就扩容(哈希数组的有效元素比上空间大小 _size*10/_ht.size()),或者无空间(哈希数组_ht.size())
扩容大小
开辟新的哈希空间
插入元素,遍历: 如果旧哈希表该节点位置存在,则插入新表
成员(指针位置,有效元素)位置交换
3.2 哈希函数计算位置:插入的值除以整体空间大小
3.3 哈希键值位置元素是否存在,存在且有值,则插入失败,否则位置加加,插入元素元素一定会存储,就会考虑下一个位置,因此判断需要用while,如果插入元素是最后一个元素位置处,就要考虑位置是否可以存储,不能存储,需要回到开头。插入元素(节点):数据、状态
4.位置交换: 成员交换(private)
5.查找元素(节点数据)
5.1.计算元素位置
5.2.判断元素位置是否存在
5.3.存在则判断值是否相等,相等则返回节点位置
5.4存在值不相等判断是否被存到其他位置
6.删除节点元素
6.1 找到元素位置
6.2 判断元素是否存在,存在:有效元素减一,状态置为DELETE
#include
#include
using namespace std;
enum State{ EMPTY, DELETE, EXIST }; //哈希表只能假删除,因此需要定义状态
//创建一个哈希节点
template<class K, class V>
struct Node //哈希节点
{
pair<K, V> _kv; //数据类型为KV模型
State _state;
};
template<class K, class V>
class HashTable
{
public:
typedef Node<K, V> Node; //节点定义为KV模型 创建了一个哈希节点的对象
HashTable(size_t n = 10) //初始化一个空的哈希表
:_ht(n)
, _size(0)
{}
bool insert(const pair<K, V>& kv)
{
//1.检查容量
CheckCapacity();
//2.计算位置
int idx = kv.first%_ht.size();
//3.判断key值是否存在
while (_ht[idx]._state != EMPTY)
{
if (_ht[idx]._state == EXIST&&_ht[idx]._kv.first == kv.first)
{
return false;
}
idx++;
if (idx == _ht.size())
{
idx = 0;
}
}
//4.插入元素
_ht[idx]._kv = kv;
_ht[idx]._state = EXIST;
}
void CheckCapacity()
{
if (_ht.size() == 0 || _size * 10 / _ht.size() >= 7)
{
//容量
int newC = _ht.size() == 0 ? 10 : 2 * _ht.size();
//开辟新的哈希空间
HashTable<K, V> newHt(newC);
//遍历插入哈希有效元素
for (int i = 0; i<_ht.size(); ++i)
{
if (_ht[i]._state == EXIST)
{
newHt.insert(_ht[i]._kv);
}
}
//交换
Swap(newHt);
}
}
void Swap(HashTable<K, V> ht)
{
swap(_ht, ht._ht);
swap(_size, ht._size);
}
Node* Find(const K& key)
{
//1.计算元素位置
int idx = key%_ht.size();
//2.判断元素位置是否存在
//3.存在则判断值是否相等,相等则返回节点位置
// 存在值不相等判断是否被存到其他位置
while (_ht[idx]._state != EXIST)
{
if (_ht[idx]._state == EXIST&&_ht[idx]._kv.first == key)
{
return &_ht[idx];
}
++idx;
if (idx == _ht.size())
{
idx = 0;
}
}
return nullptr;
}
bool erase(const K& key)
{
//假删除
//1.找到元素位置
Node* node = Find(key);
//2.节点存在则删除节点,返回true
if (node){
--_size;
node->_state = DELETE;
return true;
}
return false;
}
bool Empty() const
{
return _size == 0;
}
size_t Size() const
{
return _size;
}
private:
vector<Node> _ht; //类型为哈希节点的数组: 存储哈希数据
size_t _size; //有效元素个数
};
void test()
{
HashTable<int, int> ht;
ht.insert(make_pair(1, 1));
ht.insert(make_pair(14, 14));
ht.insert(make_pair(16, 16));
ht.insert(make_pair(11, 11));
ht.insert(make_pair(14, 140));
ht.insert(make_pair(2, 1));
ht.insert(make_pair(3, 14));
ht.insert(make_pair(5, 16));
ht.insert(make_pair(7, 11));
ht.insert(make_pair(8, 140));
ht.insert(make_pair(13, 1));
cout << ht.Find(11) << endl;
}
int main()
{
test();
system("pause");
return 0;
}