HashTable

来源:互联网 发布:阿里云服务器黑洞 编辑:程序博客网 时间:2024/05/29 17:01
#pragma once
#include <vector>


template<class K>
struct __HashFunc
{
size_t operator()(const K& key)
{
return (size_t)key;
}
};


template<>
struct __HashFunc<string>
{
static size_t BKDRHash(const char* str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313
unsigned int hash = 0;
while (*str )
{
hash = hash * seed + (*str++);
}
return hash;
}


size_t operator()(const string& s)
{
return BKDRHash(s.c_str());
}
};


namespace OPEN
{


enum State
{
EMPTY,
EXIST,
DELETE,
};


template<class K, class V>
struct HashNode
{
State _state;
K _key;
V _value;
};


template<class K, class V, class _HashFunc = __HashFunc<K>>
class HashTable
{
typedef HashNode<K, V> Node;
public:
HashTable()
:_size(0)
{}


bool Insert(const K& key, const V& value)
{
CheckCapacity();


size_t index = HashFunc(key);
size_t first = index;
size_t i = 1;
while (_tables[index]._state == EXIST)
{
if (_tables[index]._key == key)
{
return false;
}


++index;
if(index == _tables.size())
{
index = 0;
}
/* index = (first+i*i)%_tables.size();
++i;*/
}


_tables[index]._key = key;
_tables[index]._value = value;
_tables[index]._state = EXIST;
++_size;


return true;
}


Node* Find(const K& key)
{
size_t index = HashFunc(key);
while(_tables[index]._state != EMPTY)
{
if (_tables[index]._key == key)
{
if (_tables[index]._state == EXIST)
return &_tables[index];
else
return NULL;
}


++index;
if(index == _tables.size())
{
index = 0;
}
}


return NULL;
}


bool Erase(const K& key)
{
HashNode* ret = Find(key);
if (ret)
{
// 伪删除法
--_size;
ret->_state = DELETE;
}
else
{
return false;
}
}


size_t HashFunc(const K& key)
{
_HashFunc hashFunc;
return hashFunc(key)%_tables.size();
}


size_t GetNextPrime(size_t value)
{
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
};


for (size_t i = 0; i < _PrimeSize; ++i)
{
if (_PrimeList[i] > value)
{
return _PrimeList[i];
}
}

return _PrimeList[_PrimeSize-1];
}

void CheckCapacity()
{
if (_tables.size() == 0
|| _size*10/_tables.size() >= 7)
{
//size_t newSize = _tables.size() == 0 ? 10 : _tables.size()*2;
HashTable<K, V, _HashFunc> newTable;
newTable._tables.resize(GetNextPrime(_tables.size()));
for (size_t i = 0; i < _tables.size(); ++i)
{
newTable.Insert(_tables[i]._key, _tables[i]._value);
}


_tables.swap(newTable._tables);
}
}


protected:
vector<Node> _tables;
size_t _size; // 有效数据的个数
};


void TestHashTable()
{
HashTable<int, int> ht1;
ht1.Insert(89, 0);
ht1.Insert(18, 0);
ht1.Insert(49, 0);
ht1.Insert(58, 0);
ht1.Insert(9, 0);


srand(time(0));
for (size_t i = 0; i < 53; ++i)
{
ht1.Insert(rand(), 0);
}

HashTable<string, string> dict;
dict.Insert("sort", "排序");
dict.Insert("string", "字符串");
dict.Insert("insert", "插入");
dict.Insert("hash", "哈希");
dict.Insert("hhas", "哈希");
}


}




namespace LINK
{
template<class ValueType>
struct HashNode
{
ValueType _valueField;
HashNode<ValueType>* _next;


HashNode(const ValueType& v)
:_valueField(v)
,_next(NULL)
{}
};


// 前置声明
template<class K, class ValueType, class KeyOfValue, class _HashFunc = __HashFunc<K>>
class HashTable;


template<class K, class ValueType, class KeyOfValue, class _HashFunc>
struct __HashTableIterator
{
typedef HashNode<ValueType> Node;
typedef __HashTableIterator<K, ValueType, KeyOfValue, _HashFunc> Self;


Node* _node;
HashTable<K, ValueType, KeyOfValue, _HashFunc>* _hashTable;


__HashTableIterator(Node* node, HashTable<K, ValueType, KeyOfValue, _HashFunc>* hashTable)
:_node(node)
,_hashTable(hashTable)
{}


ValueType& operator*()
{
return _node->_valueField;
}


ValueType* operator->()
{
return &(operator*());
}


bool operator==(const Self& s) const
{
return _node == s._node;
}


bool operator!=(const Self& s) const
{
return _node != s._node;
}


Self& operator++()
{
if (_node->_next)
{
_node = _node->_next;
}
else
{
KeyOfValue keyOfValue;
size_t index = _hashTable->HashFunc(
keyOfValue(_node->_valueField), _hashTable->_tables.size());


Node* cur = NULL;
for (size_t i = index+1; i < _hashTable->_tables.size(); ++i)
{
if (_hashTable->_tables[i])
{
cur = _hashTable->_tables[i];
break;
}
}

_node = cur;
}


return *this;
}
};


template<class K>
struct __KeyOfKey
{
const K& operator()(const K& key)
{
return key;
}
};


template<class K, class V>
struct __KeyOfKeyValue
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};


// UnorderedMap<K, V> -> HashTable<K, pair<K, V>, __KeyOfKeyValue<K, V>>
// UnorderedSet<K>  -> HashTable<K, K, __KeyOfKey<K>>


template<class K, class ValueType, class KeyOfValue, class _HashFunc = __HashFunc<K>>
class HashTable
{
typedef HashNode<ValueType> Node;
friend struct __HashTableIterator<K, ValueType, KeyOfValue, _HashFunc>;
public:
typedef __HashTableIterator<K, ValueType, KeyOfValue, _HashFunc> Iterator;


HashTable()
:_size(0)
{}


~HashTable()
{
for (size_t i = 0; i < _tables.size(); ++i)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
_tables[i] = NULL;
}
}


Iterator Begin()
{
Node* cur = NULL;
for (size_t i = 0; i < _tables.size(); ++i)
{
if (_tables[i])
{
cur = _tables[i];
break;
}
}


return Iterator(cur, this);
}


Iterator End()
{
return Iterator(NULL, this);
}


pair<Iterator, bool> Insert(const ValueType& kv)
{
CheckCapacity();


KeyOfValue keyOfValue;
size_t index = HashFunc(keyOfValue(kv), _tables.size());
Node* cur = _tables[index];
while (cur)
{
if (keyOfValue(cur->_valueField) == keyOfValue(kv))
{
return make_pair(Iterator(cur, this), false);
}


cur = cur->_next;
}


// 头插
Node* tmp = new Node(kv);
tmp->_next = _tables[index];
_tables[index] = tmp;
++_size;
return make_pair(Iterator(tmp, this), true);
}


Iterator Find(const K& key)
{
KeyOfValue keyOfValue;
size_t index = HashFunc(key, _tables.size());
Node* cur = _tables[index];
while (cur)
{
if (keyOfValue(cur->_valueField) == key)
{
return Iterator(cur, this);
}


cur = cur->_next;
}


return End();
}


void Erase(Iterator pos)
{
KeyOfValue keyOfValue;
size_t index = HashFunc(keyOfValue(*pos), _tables.size());
Node* prev = NULL;
Node* cur = _tables[index];
while (cur)
{
if (keyOfValue(cur->_valueField) == key)
{
if (prev == NULL) // cur是头
_tables[index] = cur->_next;
else
prev->_next = cur->_next;


delete cur;
--_size;
}


prev = cur;
cur = cur->_next;
}
}


size_t Erase(const K& key)
{
Iterator pos = Find(key);
if (pos != End())
{
Erase(pos);
return 1;
}
else
{
return 0;
}
}


size_t GetNextPrime(size_t value)
{
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
};


for (size_t i = 0; i < _PrimeSize; ++i)
{
if (_PrimeList[i] > value)
{
return _PrimeList[i];
}
}


return _PrimeList[_PrimeSize-1];
}


void CheckCapacity()
{
if (_size == _tables.size())
{
KeyOfValue keyOfValue;
vector<Node*> newTables;
newTables.resize(GetNextPrime(_tables.size()));
for (size_t i = 0; i < _tables.size(); ++i)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
// 头插
size_t index = HashFunc(keyOfValue(cur->_valueField), newTables.size());
cur->_next = newTables[index];
newTables[index] = cur;


cur = next;
}


_tables[i] = NULL;
}


_tables.swap(newTables);
}
}


size_t HashFunc(const K& key, size_t size)
{
_HashFunc hashFunc;
return hashFunc(key)%size;
}


private:
vector<Node*> _tables;
size_t _size;
};




void TestHashTable()
{
HashTable<int, int, __KeyOfKey<int>> ht1; // set
ht1.Insert(1);
ht1.Insert(5);
ht1.Insert(1);
ht1.Insert(8);
HashTable<int, int, __KeyOfKey<int>>::Iterator it = ht1.Begin();
while (it != ht1.End())
{
cout<<*it<<" ";
++it;
}
cout<<endl;




HashTable<string, pair<string, string>, __KeyOfKeyValue<string, string>> ht2; // map
ht2.Insert(make_pair("sort", "排序"));
}


}