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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值