0
点赞
收藏
分享

微信扫一扫

C++手动实现HashTable


思路都写代码注释上了
头文件:

#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;
}


举报

相关推荐

0 条评论