#pragma once#include<iostream> #include <string>using namespace std;enum state{ empty,delete,exist,};template<class k, class v>struct hashtablenode{k _key; v _value;}; template<class k>struct __hashfunc //default functor {Size_t operator () that returns the hash key value keys ( Const k& key) {return key;}};/ /special String __hashfunc functor Template<>struct __hashfunc<string>{size_t operator () (const &NBSP;STRING&&NBSP;STR) {size_t key = 0;for (size_t i = 0; i < str.size (); i++) {key += str[i];} return key;}};/ /implementation of the hash table in the form of Key/value two-time detection template<class k, class v, class hashfunc = __ Hashfunc<k>>class hashtable{typedef hashtablenode<k, v> node;public: HashTable (size_t capacity = 10): _tables (new node[capacity]), _size (0), _staTES (New state[capacity]), _capacity (capacity) {// memset problematic is initialized in bytes But the second parameter value is Int//memset (_states, empty, sizeof (state) * capacity);for (size_t i = 0; i < capacity; i++) {_states[i] = empty;}} ~hashtable () {if (null != _tables) {delete[] _tables;_tables = null;} if (null != _states) {delete[] _states;_states = null;}} Bool insert (const k& key, const v& value) {_CheckCapacity ();// Solve the getnextindex conflict size_t index = _hashfunc (key);// two-time detection size_t i = 1;while (_states[index] == exist) {Index = _getnextindex (index, i++);if (index >= _capacity) {index = index % _capacity;}} _tables[index]._key = key;_tables[index]._value = value;_states[index] = exist;_size++;return true;} Node* find (Const k& key) {size_t index = _hashfunc (key); Size_t start = index;size_t i = 1;// presence or deleted Two status while (_states[index] != empty) {if (_tables[index]._key == key) {if (_states[index] == exist ) {Return index;} else // is removed delete{return -1;}} Index = _getnextindex (index, i++);if (index >= _capacity) {index = index % _capacity;} Because there is a fill factor 100% does not appear full-full and key! =_key the condition that causes the death cycle}return -1;} Bool remove (Const k& key) {int index = find (key);if (index != -1) {_states[index] = delete;--_size;return true;} Return false;} Two probes calculate the storage position Size_t _hashfunc (Const k& key) {HASHFUNC&NBSP;HF;RETURN&NBSP;HF (key) % _capacity; // Imitation function hf () &nbsP;} Hash conflict when get the next index can take advantage of the value of the previous index This can be efficient such as string's index calculation is more time-consuming size_t _getnextindex (size_t prev, size_t i) {return prev + 2 * i - 1;} Void print () {for (size_t i = 0; i < _capacity; i++) {if (_ states[i] == exist) {cout << i << "EXIST:" << _tables [i]._key << "-------" &NBSP;<<&NBSP;_TABLES[I]._VALUE&NBSP;<<&NBSP;ENDL;} else if (_states[i] == delete) {cout << i << "DELETE:" << _tables[i]._key << "-------" << _tables[i]._value << endl;} else{cout << i << "EMPTY:" << _tables[i]._key << "-------" << _tables[i]._value << endl;}}} Void swap (HASHTABLE<K,&NBsp V,&NBSP;HASHFUNC>&&NBSP;HT) {swap (_size, ht._size); swap (_states, ht._states); Swap (_tables, ht._tables); swap (_capacity, ht._capacity);} Protected:void _checkcapacity () // expansion {// Dynamic Scalable// efficient hash table The load factor is probably 0.7-0.8 better if (10 * _size / _capacity >= 7) // _size/_capacity for 0 Because all are plastic so multiply 10// to guarantee load factor within 0.7 {hashtable<k, v, hashfunc> tmp (2 * _ capacity);for (size_t i = 0; i < _capacity; i++) {if (_states[i ] == exist) {tmp. Insert (_tables[i]._key, _tables[i]._value);}} Swap (TMP);}} protected:node* _tables; state* _states;//Status Table size_t _size;size_t _capacity;};
Hash table (hash table) two probes