哈希相关概念
#pragma once
const int _PrimeSize = 28;
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
};
unsigned long GetCapacity(const int capacity)
{
int i = 0;
while (_PrimeList[i] < capacity && i < _PrimeSize)
{
i++;
}
return _PrimeList[i];
}
template <class K>
class KeyToInt
{
public:
int operator()(const int& n)
{
return n;
}
};
template <>
class KeyToInt<string>
{
public:
int operator()(string st)
{
return BKDRHash(st.c_str());
}
private:
static size_t BKDRHash(const char* str)
{
unsigned int seed = 131;
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}
};
闭散列
#include <iostream>
using namespace std;
#include "comm.hpp"
enum STATAUS
{
EMPTY, EXIST, DELETE
};
template <class K>
struct Element
{
Element()
:key(0)
,s(EMPTY)
{}
K key;
STATAUS s;
};
template <class K>
class Hash
{
public:
Hash(size_t capacity = 7)
:_size(0)
, _capacity(capacity)
{
_hash = new Element<K>[capacity];
}
bool Insert(const K& key)
{
CapacityCheck();
int addr = FunHash(key);
return LineCheck(addr, key);
}
bool Find(const K& key)
{
int addr = FunHash(key);
int oldaddr = addr;
while (_hash[addr].key != key)
{
addr++;
if (addr == _capacity)
{
addr = 0;
}
if (addr == oldaddr)
{
return false;
}
}
return true;
}
bool Emase()
{
int addr = FunHash(key);
int oldaddr = addr;
while (_hash[addr].key != key)
{
addr++;
if (addr == _capacity)
{
addr = 0;
}
if (addr == oldaddr)
{
return false;
}
}
_hash[addr].s = DELETE;
size--;
return true;
}
~Hash()
{
if (_hash)
{
delete[] _hash;
_hash = NULL;
_size = 0;
_capacity = 0;
}
}
private:
void CapacityCheck()
{
if (_size * 10 / _capacity > 7)
{
int newcapacity = GetCapacity(_capacity);
Hash temp(newcapacity);
Swap(temp);
_capacity = newcapacity;
}
}
int FunHash(const K& key)
{
return key%_capacity;
}
void Swap(Hash& s)
{
for (int i = 0; i < _size; ++i)
{
s.Insert(_hash[i].key);
}
swap(_hash, s._hash);
s._size = _size;
}
bool LineCheck(int addr, const K& key)
{
int oldaddr = addr;
while (_hash[addr].s != EMPTY)
{
addr++;
if (addr == _capacity)
{
addr = 0;
}
if (addr == oldaddr)
{
return false;
}
}
_hash[addr].key = key;
_hash[addr].s = EXIST;
_size++;
return true;
}
bool Secondcheck()
{
int oldaddr = addr;
int i = 1;
while (_hash[addr].s != EMPTY)
{
addr += i*i;
i++;
if (addr == _capacity)
{
addr = 0;
}
if (addr == oldaddr)
{
return false;
}
}
_hash[addr].key = key;
_hash[addr].s = EXIST;
_size++;
return true;
}
Element<K>* _hash;
size_t _size;
size_t _capacity;
};
void Funtest()
{
int arr[] = { 37, 25, 14, 36, 49, 68, 57, 11 };
Hash<int> h;
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
h.Insert(arr[i]);
}
}
开散列
#include <vector>
template<typename K, typename V>
struct ELEM
{
ELEM()
: pnext(NULL)
{
}
ELEM(const K& key, const V& val = V())
:_val(make_pair(key, val))
, pnext(NULL)
{}
pair<K, V> _val;
ELEM* pnext;
};
template <class K, class V, class KeyToInt>
class HashTab;
template <class K, class V, class KeyToInt>
class HashIterator
{
typedef ELEM<K, V> Node;
typedef Node* pNode;
typedef HashIterator<K, V, KeyToInt> Slef;
public:
HashIterator()
:_Hash(NULL)
{}
HashIterator( HashTab<K, V, KeyToInt>* hb, const pNode& pcur)
:_Hash(hb)
, _pHead(pcur)
{
}
Slef& operator++()
{
_Pnext();
return *this;
}
Slef operator++(int)
{
Slef temp(*this);
_Pnext();
return temp;
}
pair<K, V> operator*()
{
return _pHead->_val;
}
pNode operator->()
{
return _pHead;
}
bool operator==(const Slef& s)
{
return ((_Hash == s._Hash) && (s._pHead == _pHead));
}
bool operator!=(const Slef& s)
{
return !(operator==(s));
}
private:
void _Pnext()
{
size_t index = _Hash->FunHash((*_pHead)._val.first);
if (_pHead)
{
_pHead = _pHead->pnext;
}
while ((_pHead == NULL) && (index < (_Hash->_capacity -1)))
{
index++;
_pHead = _Hash->_HashBucket[index];
}
if (index >= _Hash->_HashBucket.size() - 1)
{
return;
}
}
HashTab<K, V, KeyToInt>* _Hash;
pNode _pHead;
};
template <typename K, typename V, typename KeyToInt = KeyToInt<K>>
class HashTab
{
friend class HashIterator<K, V, KeyToInt>;
typedef ELEM<K, V> Node;
typedef Node* pNode;
public: typedef HashIterator<K, V, KeyToInt> Iterator;
public:
HashTab(const int& capacity = 2)
: _size(0)
, _capacity(capacity)
{
_HashBucket.resize(_capacity);
for (size_t i = 0; i < _capacity; i++)
{
_HashBucket[i] = NULL;
}
}
bool InsertUnique(const K& key, const V& value)
{
Cheakcapacity();
int addr = FunHash(key);
pNode pcur = _HashBucket[addr];
if (pcur == NULL)
{
pNode temp = new Node(key, value);
_HashBucket[addr] = temp;
}
else
{
pNode pre = NULL;
while (pcur)
{
if (pcur->_val.first == key)
{
return false;
}
pre = pcur;
pcur = pcur->pnext;
}
pNode temp = new Node(key, value);
if (pre)
pre->pnext = temp;
}
_size++;
return true;
}
bool InsertEqual(const K& key, const V& value)
{
Cheakcapacity();
int addr = FunHash(key);
pNode pcur = _HashBucket[addr];
pNode temp = new Node(key, value);
if (pcur == NULL)
{
_HashBucket[addr] = temp;
}
else
{
temp->pnext = pcur->pnext;
pcur->pnext = temp;
}
_size++;
return true;
}
bool EraseUnique(const K& key)
{
int addr = FunHash(key);
pNode pcur = _HashBucket[addr];
pNode pre = NULL;
if (pcur && pcur->_val.first == key)
{
_HashBucket[addr] = pcur->pnext;
delete pcur;
pcur = NULL;
_size--;
return true;
}
else
{
while (pcur)
{
pre = pcur;
pcur = pcur->pnext;
if (pcur->_val.first == key)
{
pre->pnext = pcur->pnext;
delete pcur;
pcur = NULL;
_size--;
return true;
}
}
return false;
}
}
bool EraseEqual(const K& key)
{
int addr = FunHash(key);
bool flag = false;
pNode pcur = _HashBucket[addr];
pNode pre = NULL;
while (pcur && pcur->_val.first == key)
{
_HashBucket[addr] = pcur->pnext;
delete pcur;
pcur = NULL;
_size--;
flag = true;
pcur = _HashBucket[addr];
}
while (pcur)
{
pre = pcur;
pcur = pcur->pnext;
if (pcur->_val.first == key)
{
pre->pnext = pcur->pnext;
delete pcur;
pcur = NULL;
_size--;
flag = true;
}
}
return flag;
}
Iterator Begin()
{
size_t index = 0;
pNode pcur = _HashBucket[index];
while (pcur == NULL && index < (_capacity-1))
{
index++;
pcur = _HashBucket[index];
}
return Iterator(this, pcur);
}
Iterator End()
{
return Iterator(this, NULL);
}
size_t Size()
{
return _size;
}
pair<bool, Iterator> Find(const K& key)
{
int addr = FunHash(key);
pNode pcur = _HashBucket[addr];
pNode pre = NULL;
while (pcur)
{
if (pcur->_val.first == key)
{
return pair<bool, Iterator>(true, Iterator(this, pcur));
}
pre = pcur;
pcur = pcur->pnext;
}
pNode temp = new Node(key);
if (pre)
{
pre->pnext = temp;
return pair<bool, Iterator>(false, Iterator(this, temp));
}
else
{
_HashBucket[addr] = temp;
return pair<bool, Iterator>(false, Iterator(this, temp));
}
}
bool operator==(const HashTab<K, V, KeyToInt> s)
{
return true;
}
private:
bool Cheakcapacity()
{
if (_HashBucket.size() == _size)
{
int newcapacity = GetCapacity(_size);
HashTab<K, V, KeyToInt> temp(newcapacity);
Swap(temp);
_capacity = newcapacity;
return true;
}
return false;
}
void Swap( HashTab<K, V, KeyToInt>& s)
{
vector<pNode> temp;
for (size_t i = 0; i < _size; ++i)
{
s.InsertEqual((_HashBucket[i]->_val).first, (_HashBucket[i]->_val).second);
}
swap(_HashBucket, s._HashBucket);
}
int FunHash(const K& key)
{
int ret = KeyToInt()(key);
return ret%_capacity;
}
vector<pNode> _HashBucket;
size_t _size;
size_t _capacity;
};
void HashTabTest()
{
HashTab<int, int> HAT;
HAT.InsertEqual(11, 11);
HAT.InsertEqual(12, 12);
HAT.InsertEqual(11, 11);
HAT.InsertEqual(11, 11);
HAT.InsertEqual(13, 13);
HAT.InsertEqual(12, 12);
cout << (*(HAT.Find(11)).second).first<< endl;
cout << (*(HAT.Find(14)).second).first << endl;;
HashTab<int, int>::Iterator It = HAT.Begin();
while (It != HAT.End())
{
cout << (*It).second << " ";
It++;
}
cout << endl;
HAT.EraseEqual(12);
HAT.EraseEqual(11);
}