思路都写代码注释上了
头文件:
#ifndef _HASHTABLE_H_
#define _HASHTABLE_H_
#include <iostream>
#include <list>
#include <memory>
#include <queue>
/*元素节点类*/
class Node {
public:
Node(int key = 0, int val = 0, bool isexit = false)
: _key(key), _val(val), _isExit(isexit) {}
int _key, _val;
bool _isExit;
};
class HashTable {
public:
/*构造函数*/
HashTable();
/*找到val的key值*/
int find(int val);
/*插入数据*/
void insert(int x);
/*删除元素*/
void erase(int x);
/*获取元素*/
int getval(int key);
/*获取元素个数*/
int getsize();
/*获取内存长度*/
int getcapcity();
private:
/*存放数据的容器*/
Node* _arry;
/*容器中元素数量*/
int _size;
/*容器内存*/
int _capcity;
/*平衡因子*/
float _factor;
/*扩容因子*/
int _expansionFactor;
/*检查是否可以进行扩容*/
bool isExpansion();
/*自动扩容*/
void AutoExpansion();
/*重新分配内存后需要重新hash*/
Node ReHash(Node& _arry1);
/*释放内存*/
void ReaseMemory(Node* tmp);
/*哈希函数1*/
int Hash1(int val);
/*哈希函数2*/
int Hash2(int val);
/*哈希函数3*/
int Hash3(int val);
/*真正使用的哈希函数*/
int Hash(int val);
};
#endif
#include "hashtable.h"
/*私有成员*/
HashTable::HashTable() {
_size = 0;
_capcity = 10;
_factor = 0.7;
_arry = new Node[_capcity];
_expansionFactor = 2;
}
HashTable::~HashTable() {
if (_arry != nullptr) {
delete[] _arry;
}
}
bool HashTable::isExpansion() {
float xs = 1.0 * _size / _capcity;
return xs >= _factor;
}
Node HashTable::ReHash(Node& _arry1) {
Node node(0, 0, false);
node._val = _arry1._val;
node._key = Hash(node._val);
node._isExit = true;
return node;
}
void HashTable::AutoExpansion() {
int Len = _capcity;
_capcity *= _expansionFactor;
Node* arry = new Node[_capcity];
Node* tmp = _arry;
_arry = arry;
for (int i = 0; i < Len; i++) {
if (tmp[i]._isExit) {
auto node = ReHash(tmp[i]);
arry[node._key] = node;
}
}
ReaseMemory(tmp);
}
void HashTable::ReaseMemory(Node* tmp) {
delete[] tmp;
}
int HashTable::Hash1(int val) {
int times = 3;
int k = 1;
while (times--) {
val = (val + k * k + _capcity) % _capcity;
k++;
}
return val;
}
int HashTable::Hash2(int val) {
int times = 2;
while (times--) {
val = (val + 1 + _capcity) % _capcity;
}
return val;
}
int HashTable::Hash3(int val) {
int times = 4;
while (times--) {
val = (val + times * 51 + _capcity) % _capcity;
}
return val;
}
int HashTable::Hash(int val) {
int nowval = val;
do {
val = Hash1(Hash2(Hash3(val)));
} while (_arry[val]._isExit && (nowval != _arry[val]._val));
return val;
}
/*共有成员*/
void HashTable::insert(int val) {
Node node(0, 0, false);
node._key = Hash(val);
if (_arry[node._key]._isExit) {
return;
}
node._val = val;
node._isExit = true;
_arry[node._key] = node;
_size++;
if (isExpansion()) {
AutoExpansion();
}
}
int HashTable::find(int val) {
int key = Hash(val);
return _arry[key]._isExit ? key : -1;
}
int HashTable::getval(int key) {
return _arry[key]._val;
}
int HashTable::getsize() {
return _size;
}
int HashTable::getcapcity() {
return _capcity;
}
void HashTable::erase(int x) {
int key = find(x);
_arry[key] = Node{0, 0, false};
_size--;
}
测试代码
#include <time.h>
#include <algorithm>
#include <vector>
#include "hashtable.h"
int main() {
/*测试find,insert是否精准*/
HashTable test;
std::vector<int> v(1000000, 0);
std::vector<int> _Ms(1000000, 0);
for (int i = 0; i < 1000000; i++) {
// v[i] = rand();
test.insert(i);
}
for (int i = 0; i < 1000000; i++) {
int start = clock();
int a = test.find(i);
int end = clock();
_Ms[i] = end - start;
if (test.getval(a) != i) {
puts("-1");
}
}
std::sort(_Ms.begin(), _Ms.end());
std::cout << _Ms[_Ms.size() - 1] << std::endl;
std::cout << test.getsize() << std::endl;
test.erase(5);
std::cout << test.find(5) << std::endl;
std::cout << test.getsize() << std::endl;
return 0;
}