哈希表的改造
1.模板参数列表的改造
template<class K, class V, class KeyOfValue, class HF = DefHashF<T> >
class HashTable;
2.增加迭代器操作
template<class K,class V,class KeyOfValue,class HashFun>
struct Hash_Iterator{
typedef HashNode<V> Node;
typedef Node* pNode;
typedef Hash_Iterator<K,V,KeyOfValue,HashFun> Self;
typedef HashTable<K,V,KeyOfValue,HashFun> HashT;
pNode _node;
HashT* _ht;
Hash_Iterator(pNode node,HashT* ht)
:_node(node)
,_ht(ht)
{
}
V& operator*(){
return _node->_data;
}
V* operator->(){
return &(operator*());
}
bool operator!=(const Self& it){
return _node != it._node;
}
Self& operator++(){
if(_node->_next){
_node=_node->_next;
}else{
KeyOfValue Kov;
size_t index=_ht->HashIndex( Kov(_node->_data),_ht->_table.size() );
++index;
for(;index<_ht->_table.size();++index){
if(_ht->_table[index]){
_node= _ht->_table[index];
break;
}
}
if(index==_ht->_table.size()){
_node=nullptr;
}
}
return *this;
}
};
3.增加通过key获取value操作
size_t HashIndex(const K& key,size_t sz){
HashFun hfun;
return hfun(key)%sz;
}
哈希表的模拟实现(hash.hpp)
#pragma once
#include<iostream>
#include<vector>
using namespace std;
template <class V>
struct HashNode{
HashNode<V>* _next;
V _data;
HashNode(const V& data)
:_next(nullptr)
,_data(data)
{
}
};
template<class K,class V,class KeyOfValue,class HashFun>
class HashTable;
template<class K,class V,class KeyOfValue,class HashFun>
struct Hash_Iterator{
typedef HashNode<V> Node;
typedef Node* pNode;
typedef Hash_Iterator<K,V,KeyOfValue,HashFun> Self;
typedef HashTable<K,V,KeyOfValue,HashFun> HashT;
pNode _node;
HashT* _ht;
Hash_Iterator(pNode node,HashT* ht)
:_node(node)
,_ht(ht)
{
}
V& operator*(){
return _node->_data;
}
V* operator->(){
return &(operator*());
}
bool operator!=(const Self& it){
return _node != it._node;
}
Self& operator++(){
if(_node->_next){
_node=_node->_next;
}else{
KeyOfValue Kov;
size_t index=_ht->HashIndex( Kov(_node->_data),_ht->_table.size() );
++index;
for(;index<_ht->_table.size();++index){
if(_ht->_table[index]){
_node= _ht->_table[index];
break;
}
}
if(index==_ht->_table.size()){
_node=nullptr;
}
}
return *this;
}
};
template <class K,class V,class KeyOfValue,class HashFun>
class HashTable{
public:
typedef HashNode<V> Node;
typedef Node* pNode;
template<class Key,class Val,class SKeyOfValue,class SHashFun>
friend struct Hash_Iterator;
typedef Hash_Iterator<K,V,KeyOfValue, HashFun> Iterator;
public:
Iterator begin(){
for(size_t i=0;i<_table.size();++i){
if(_table[i]){
return Iterator(_table[i],this);
}
}
return Iterator(nullptr,this);
}
Iterator end(){
return Iterator(nullptr,this);
}
public:
pair<Iterator,bool> Insert(const V& data){
CheckCapacity();
KeyOfValue Kov;
size_t index=HashIndex(Kov(data),_table.size());
pNode cur=_table[index];
while(cur){
if(Kov(cur->_data)== Kov(data)){
return make_pair(Iterator(cur,this),false);
}
cur=cur->_next;
}
cur=new Node(data);
cur->_next=_table[index];
_table[index]=cur;
++_size;
return make_pair(Iterator(cur,this),true);
}
size_t getNextPrime(const size_t prime)
{
static const int PRIMECOUNT = 28;
static const size_t primeList[PRIMECOUNT] =
{
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 < PRIMECOUNT; ++i)
{
if (primeList[i] > prime)
return primeList[i];
}
return primeList[PRIMECOUNT - 1];
}
void CheckCapacity(){
if(_size==_table.size()){
size_t newC=getNextPrime(_table.size());
KeyOfValue Kov;
vector<pNode> newHt;
newHt.resize(newC);
for(size_t i=0;i<_table.size();i++){
pNode cur=_table[i];
while(cur){
pNode next=cur->_next;
size_t index=HashIndex(Kov(cur->_data),newHt.size());
cur->_next=newHt[index];
newHt[index]=cur;
cur=next;
}
_table[i]=nullptr;
}
_table.swap(newHt);
}
}
Iterator Find(const K& key){
size_t index=HashIndex(key,_table.size());
pNode cur=_table[index];
KeyOfValue kov;
while(cur){
if(kov(cur->data)==key)
return Iterator(cur,this);
}
return end();
}
bool Erase(const K& key){
size_t index=HashIndex(key,_table.size());
pNode cur=_table[index];
pNode prev=nullptr;
KeyOfValue kov;
while(cur){
if(kov(cur->_data)==key){
if(prev){
prev->_next=cur->_next;
}
else
_table[index]=cur->_next;
delete cur;
--_size;
return true;
}
prev =cur;
cur=cur->_next;
}
return false;
}
size_t HashIndex(const K& key,size_t sz){
HashFun hfun;
return hfun(key)%sz;
}
private:
vector<pNode> _table;
size_t _size=0;
};