在这里不赘述哈希表的相关性质有兴趣的参考线性探测,这里直接贴代码
template<class T>
struct HashNode
{
T _data;
HashNode<T>* _next;
HashNode(const T& data)
:_data(data), _next(nullptr)
{
}
};
template<class K, class T, class KOFV>
class HashTable
{
typedef HashNode<T> Node;
public:
bool Insert(const T& data)
{
KOFV kofv;
//也需要控制负载因子,一般控制在1比较好
if (_num == _tables.size())
{
vector<Node*> newtables;
int newcapacity = _tables.size() == 0 ? 10 : _tables.size() * 2;
newtables.resize(newcapacity);
for (int i = 0; i < _tables.size(); i++)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
int index = kofv(cur->_data) % newcapacity;
cur->_next = newtables[index];
newtables[index] = cur;
cur = next;
}
_tables[i] = nullptr;
}
_tables.swap(newtables);
}
int index = kofv(data) % _tables.size();
Node* cur = _tables[index];
while (cur)
{
if (kofv(cur->_data) == kofv(data))
{
return false;
}
else
{
cur = cur->_next;
}
}
//头插到链表中(尾插也可以)
Node* newnode = new Node(data);
newnode->_next = _tables[index];
_tables[index] = newnode;
++_num;
return true;
}
Node* Find(const K& key)
{
KOFV kofv;
size_t index = key % _tables.size();
Node* cur = _tables[index];
while (cur)
{
if (kofv(cur->_data) == key)
return cur;
else
cur = cur->_next;
}
return nullptr;
}
bool Erase(const K& key)
{
KOFV kofv;
size_t index = key % _tables.size();
Node* cur = _tables[index];
Node* prev = nullptr;
while (cur)
{
if (kofv(cur->_data) == key)
{
if (prev == nullptr)
_tables[index] = cur->_next;
else
prev = cur->_next;
delete cur;
return true;
}
else
{
prev = cur;
cur = cur->_next;
}
}
return false;
}
private:
vector<Node*> _tables;
size_t _num = 0;
};
template<class K>
struct SetkeyOfv
{
const K& operator()(const K& key)
{
return key;
}
};
哈希捅和线性探测的区别就在于,哈希桶的结构体中的vector,存的是指针,而线性探测存的的是状态和信息