“test.cpp”
#include<iostream>
using namespace std;
#include"HashList.h"
#include<string>
void test()
{
HashList<string,int> hl;
string str[] = {"hash","table","xiao","hai","xia"};
size_t size = sizeof(str)/sizeof(str[0]);
for(int i = 0;i < size;i++)
{
hl.Insert(str[i],i);
}
hl.Display();
cout<<endl;
hl.Remove("xiao");
hl.Display();
}
int main()
{
test();
system("pause");
return 0;
}
“HashList.h”
#pragma once
#include<vector>
#include<string>
template<class K,class V>
struct KVNode
{
K _key;
V _value;
KVNode<K,V>* _next;
KVNode(const K& key = K(),const V& value = V())
:_key(key)
,_value(value)
,_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;
unsigned int hash = 0;
while(*str)
{
hash = hash*seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}
size_t operator()(const string& str)
{
return BKDRHash(str.c_str());
}
};
template<class K,class V,class HashFunc = __HashFunc<K>>
class HashList
{
typedef KVNode<K,V> Node;
public:
HashList()
:_size(0)
{}
~HashList()
{
for(int i = 0; i < _table.size();i++)
{
Node* cur = _table[i];
while(cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
}
_size = 0;
_table.clear();
}
public:
Node* Find(const K& key)
{
for (int i = 0;i < _table.size();i++)
{
Node* cur = _table[i];
while (cur)
{
if (cur->_key == key)
{
return cur;
}
cur = cur->_next;
}
}
return NULL;
}
bool Remove(const K& key)
{
//繁琐啰嗦的解法
//Node* prev = NULL;
//for (int i = 0;i < _table.size();i++)
//{
// Node* cur = _table[i];
// while (cur)
// {
// if (cur->_key == key)
// {
// //判断删除的是否为头结点
// if (prev == NULL)
// _table[i] = cur->_next;
// else
// //删除节点不是头结点
// prev->_next = cur->_next;
//
// delete cur;
// return true;
// }
// prev = cur;
// cur = cur->_next;
// }
//}
//return false;
size_t index = _HashFunc(key,_table.size());
Node* cur = _table[index];
Node* prev = NULL;
while (cur)
{
if (cur->_key == key)
{
//判断删除的是否为头结点
if (prev == NULL)
_table[index] = cur->_next;
else
//删除节点不是头结点
prev->_next = cur->_next;
delete cur;
return true;
}
prev = cur;
cur = cur->_next;
}
return false;
}
bool Insert(const K& key,const V& value)
{
_Check();
if (Find(key))
{
return false;
}
size_t index = _HashFunc(key,_table.size());
Node* cur = new Node(key,value);
//头插法
cur->_next = _table[index];
_table[index] = cur;
_size++;
return true;
}
void Display()
{
for (int i = 0;i < _table.size();i++)
{
Node* cur = _table[i];
cout<<"table["<<i<<"] = ";
while (cur)
{
//cout<<"_table["<<i<<"] = "<<cur->_key<<"->";
cout<<cur->_key<<"->";
cur = cur->_next;
}
cout<<"NULL"<<endl;
}
}
protected:
void _Check()
{
//第一次进来时,和当负载因子为1时
if (_table.size() == 0 || _size == _table.size())
{
int size = _GetPrimeNum(_table.size());
//HashList<K,V,HashFunc> tmp;
vector<Node*> tmp;
tmp.resize(size);
for (int i = 0;i < _table.size();i++)
{
Node* cur = _table[i];
while (cur)
{
//从旧表中取下节点
Node* next = cur->_next;
_table[i] = next;
//取出的节点重新插入
size_t index = _HashFunc(cur->_key,tmp.size());
cur->_next = tmp[index];
tmp[index] = cur;
cur = next;
}
}
tmp.swap(_table);
}
}
size_t _HashFunc(const K& key,size_t size)
{
HashFunc hf;
return hf(key)%size;
}
size_t _GetPrimeNum(int num)
{
// 使用素数表对齐做哈希表的容量,降低哈希冲突
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(int i = 0;i < _PrimeSize;i++)
{
if(num < _PrimeList[i])
return _PrimeList[i];
}
return _PrimeList[_PrimeSize - 1];
}
private:
vector<Node*> _table;
size_t _size;
};