the structure of a hash bucket
Open Chain/zipper method for handling hash conflicts--hash bucket
use primes to make hash table lengths to reduce hash collisions
Prime Numbers table
size_t getnextprime (size_t num)/Prime number table
{
const int _primesize =;
static const unsigned long _primelist[_primesize] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul , 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul,
12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul,
3221225473ul, 4294967291ul
};
for (size_t i = 0; i < _primesize. ++i)
{
if (_primelist[i] > num)
{return
_primelist[i];
}
return
_primelist[_primesize-1];
}
Definition of the node of the hash bucket
Template <class k,class v>
struct Hashnode
, pair<k v>
;
Hashnode<k, v>* _next;
Hashnode (const pair<k, v>& kv)
: _kv (KV)
, _next (NULL)
{}
};
Insert of a hash bucket
Check the capacity, and the load factor, before inserting. If not enough, increase the capacity by increasing the number of primes to reduce the hash conflict.
Inserts after the location is found, and each insertion is inserted into the next node of the table. Such as:
When inserted is empty:
When you insert a node:
Code:
BOOL Insert (const pair<k, v>& kv)
{
_check ();
size_t index = _hashfunc (Kv.first,_tables.size ());
node* cur = _tables[index];
while (cur)
{
if (Cur->_kv.first = = Kv.first) return
false;
cur = cur->_next;
}
node* tmp = new Node (kv);
Tmp->_next = _tables[index];
_tables[index] = tmp;
++_size;
return true;
}
Hash Bucket Lookup
Finds a node from one of the table's locations, there is a return node, and no return is empty.
Code:
node* Find (const k& key)
{
size_t index = _hashfunc (key, _tables.size ());//Determine the location of the table
node* cur = _tables[ index];
while (cur)
{
if (Cur->_kv.first = = key)//exists return
cur;
Cur = cur->_next;//does not exist
} return
NULL;
}
removal of hash bucket
The node is found first, the deletion is found, the deletion returns True, and false is not found.
Delete in two cases:
First, delete the first node of the table. (such as: 2, 3)
The second is the opposite of the first. (such as: 53, 105)
Code:
BOOL Remove (const k& key)
{
size_t index = _hashfunc (key, _tables.size ());//Determine the location of the table
node* cur = _tables[ index];
node* prev = NULL;
while (cur)
{
if (Cur->_kv.first = = key)
{
if (prev = NULL)//First case
_tables[index] = cur->_ Next;
Else//prev!= null//The second case
Prev->_next = cur->_next;
Delete cur;
--_size;
return true;
}
prev = cur;
cur = cur->_next;
}
return false;
}
Code:
"HashTablest.h" #pragma once #include <vector> template <class k,class v> struct Hashnode {pair<k, V
> _kv;
Hashnode<k, v>* _next;
Hashnode (const pair<k, v>& kv): _kv (KV), _next (NULL) {}};
Template <class k> struct __hashfunc {size_t operator () (const k& key) {return key;
}
}; template<> struct __hashfunc<string> {static size_t bkdrhash (const char* str) {unsigned int
Seed = 131;//131 1313 13131 131313 unsigned int hash = 0;
while (*STR) {hash = Hash*seed + (*str++);
Return (hash & 0x7fffffff);
} size_t operator () (const string& key) {return Bkdrhash (Key.c_str ());
}
}; Template <class k,class V,class hashfunc = __hashfunc<k>> class HashTable {typedef hashnode<k, v> N
Ode Public:hashtable (): _size (0) {} HashTable (const Hashtable<k,v,hashfunc>& ht): _size (0) {_tables.resize (Ht._tables.size ());
for (size_t i = 0; i < ht._tables.size (); ++i) {node* cur = ht._tables[i];
while (cur) {Insert (CUR->_KV);
Cur = cur->_next;
}} ~hashtable () {_clear ();
} void Resize (size_t n) {_check (n);
BOOL Insert (const pair<k, v>& kv) {_check ();
size_t index = _hashfunc (Kv.first,_tables.size ());
node* cur = _tables[index];
while (cur) {if (Cur->_kv.first = = Kv.first) return false;
Cur = cur->_next;
} node* tmp = new Node (KV);
Tmp->_next = _tables[index];
_tables[index] = tmp;
++_size;
return true; } node* Find (const k& key) {size_t index = _hashfunc (KEY, _tables.size ());
node* cur = _tables[index];
while (cur) {if (Cur->_kv.first = = key) return cur;
Cur = cur->_next;
return NULL;
BOOL Remove (const k& key) {size_t index = _hashfunc (key, _tables.size ());
node* cur = _tables[index];
node* prev = NULL;
while (cur) {if (Cur->_kv.first = = key) {if (prev = NULL)
_tables[index] = cur->_next;
Else//prev!= NULL prev->_next = cur->_next;
Delete cur;
--_size;
return true;
} prev = cur;
Cur = cur->_next;
return false; } protected:void _clear () {for (size_t i = 0; i < _tables.size (); ++i) {node* C
ur = _tables[i];
while (cur) {node* next = cur->_next;
Delete cur;
cur = next;
} _tables[i] = NULL;
} _size = 0;
} void _check (size_t n = 0) {if (_tables.size () < n | | | _tables.size () = = _size) {
if (_tables.size () > N) n = _tables.size ();
Vector<node*> newhashtable;
Newhashtable.resize (Getnextprime (n));
for (size_t i = 0; i < _tables.size (); ++i) {node* cur = _tables[i];
while (cur) {node* next = cur->_next;
size_t index = _hashfunc (Cur->_kv.first, Newhashtable.size ());
Cur->_next = Newhashtable[index];
Newhashtable[index] = cur;
cur = next;
} _tables[i] = NULL; } _tables.swap (Newhashtable);
} size_t _hashfunc (const k& key,size_t N) {return hashfunc () (key)% n;
} size_t getnextprime (size_t num)/prime number Table {const int _primesize = 28; static const unsigned long _primelist[_primesize] = {53ul, 97ul, 193ul, 389ul, 769ul, 154 3ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul,
3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul};
for (size_t i = 0; i < _primesize ++i) {if (_primelist[i] > num) {
return _primelist[i];
} return _primelist[_primesize-1];
} protected:vector<node*> _tables;
size_t _size;
}; void Testhashtablest () {int a[] = {51, 105, 52, 3, 55, 2,106, 53, 0};
Hashtable<int, int> ht1; for (size_t i = 0; i < sizeof (a)/sizeof (a[0)); ++i) {ht1.
Insert (Make_pair (a[i], i)); } ht1.
Find (51); Ht1.
Remove (51); Ht1.
Find (51); Ht1.
Remove (2); Ht1.
Remove (3); Ht1.
Remove (53); Ht1.
Remove (105); Ht1.
Find (2); Ht1.
Find (3);
} "Test.cpp" #include <iostream> using namespace std;
#include "HashTablest.h" int main () {testhashtablest ();
return 0; }