前面发了几篇博客,一个评语都没有,这次废话不多说,直接上代码。有讨论的话再给出代码介绍。请尊重原创!!!
#ifndef QUICK_HASH_H
#define QUICK_HASH_H
#include <cstdio>
#include <cstring>
/**@file QuickHash.h
* 实现Hash功能的模板类
* @author xiaoxing.zhou
* @date 2012-4-25
* @version v1.0
*/
/**@struct
* 定义比较操作
*/
struct Equal
{
static bool equal(int a, int b){return a==b;};
static bool equal(const char* pStr1, const char* pStr2){return strcmp(pStr1,pStr2)==0;};
};
/**@struct
* 定义Hash函数
*/
struct Hash
{
static int hash(int a){return a;}
static int hash(const char* pStr)
{
int b = 378551;
int a = 63689;
int hash = 0;
while (*pStr){
hash = hash * a + (*pStr++);
a *= b;
}
return (hash & 0x7FFFFFFF);
}
};
/**@struct
* 定义Hash链表结点
*/
template<typename Key, typename Value, typename Equal>
class HashNode
{
public:
typedef HashNode<Key, Value, Equal> Node;
HashNode(const Key& key, const Value& value)
{
m_key=key;
m_value=value;
m_pPrev=NULL;
m_pNext=NULL;
}
~HashNode()
{
/**前向删除结点*/
if(m_pPrev)delete m_pPrev;
/**后向删除结点*/
if(m_pNext)delete m_pNext;
}
const Key& GetKey(){return m_key;}
Value& GetValue(){return m_value;}
void SetValue(const Value& value){m_value=value;}
void SetPrev(HashNode* pPrev){m_pPrev=pPrev;}
void SetNext(HashNode* pNext){m_pNext=pNext;}
Node* PrevNode(){return m_pPrev;}
Node* NextNode(){return m_pNext;}
/**前插入结点*/
void FrontInsert(Node* pNode)
{
pNode->m_pNext=this;
pNode->m_pPrev=m_pPrev;
}
/**后插入结点*/
void BackInsert(Node* pNode)
{
pNode->m_pNext=m_pNext;
m_pNext=pNode;
}
/**移除结点*/
void Remove()
{
if(m_pPrev){
m_pPrev->m_pNext=m_pNext;
if(m_pNext)m_pNext->m_pPrev=pTemp;
}
else{
m_pNext->m_pPrev=NULL;
}
m_pPrev=NULL;
m_pNext=NULL;
}
/**交换两个结点顺序*/
void Swap(Node* pNode)
{
if(pNode && this!=pNode){//!不允许同一结点交换
Node* pTemp=m_pPrev;
pNode->m_pPrev=m_pPrev;
m_pPrev=pTemp;
pTemp=pNode->m_pNext;
pNode->m_pNext=m_pNext;
m_pNext=pTemp;
}
}
/**遍历链表查找结点*/
Node* Find(const Key& key)
{
if(Equal::equal(m_key,key))return this;
Node* pTemp=m_pNext;
while(pTemp){
if(Equal::equal(pTemp->m_key,key))return pTemp;
pTemp=pTemp->m_pNext;
}
pTemp=m_pPrev;
while(pTemp){
if(Equal::equal(pTemp->m_key,key))return pTemp;
pTemp=pTemp->m_pPrev;
}
return NULL;
}
/**判断是否相临*/
bool Adjacent(Node* pNode)
{
return pNode->m_pNext==this||pNode->m_pPrev=this;
}
/**后续结点个数*/
int NextNum()
{
Node* pTemp=m_pNext;
int num=0;
while(pTemp){
++num;
pTemp=pTemp->m_pNext;
}
return num;
}
/**前驱结点个数*/
int PrevNum()
{
Node* pTemp=m_pPrev;
int num=0;
while(pTemp){
++num;
pTemp=pTemp->m_pPrev;
}
return num;
}
protected:
Node* m_pPrev;
Node* m_pNext;
Key m_key;
Value m_value;//!要求保存的数据可以复制
//friend template<typename Key, typename Value, typename Equal, typename Hash, int Size>class QuickHash;
};
/**@class
* 定义Hash类
*/
template<typename Key, typename Value, typename Equal, typename Hash, int Size=1000>
class QuickHash
{
public:
typedef HashNode<Key, Value, Equal> Node;
QuickHash()
{
m_HashSize=Size;
m_pHashTable=new Node*[m_HashSize];
for(int i=0; i<m_HashSize; ++i){
m_pHashTable[i]=NULL;
}
}
~QuickHash()
{
for(int i=0; i<m_HashSize; ++i){
if(m_pHashTable[i])delete m_pHashTable[i];
}
delete[] m_pHashTable;
}
//!扩大尺寸
void Resize(int size)
{
if(size>m_HashSize){//!扩大尺寸
Node** pHashTable=new Node[size];
Node* pNode;
Node* pTemp;
int key;
for(int i=0; i<m_HashSize; ++i){
pNode=m_pHashTable[i];
if(pNode){
key=Hash::hash(pNode->GetKey())%size;
pTemp=pHashTable[key];
if(pTemp){
pTemp->FrontInsert(pNode);
}
else pHashTable[key]=pNode;
}
}
delete[] m_pHashTable;
m_pHashTable=pHashTable;
m_HashSize=size;
}
}
//!插入键值对
bool Insert(const Key& key, const Value& value)
{
int index=Hash::hash(key)%m_HashSize;
if(index<0&&index>=m_HashSize)return false;
Node* pNode=m_pHashTable[index];
Node* pNew=new Node(key,value);
if(pNode)pNode->BackInsert(pNew);
else m_pHashTable[index]=pNew;
return true;
}
//!删除键值对
bool Delete(const Key& key, const Value& value)
{
int index=Hash::hash(key)%m_HashSize;
if(index<0&&index>=m_HashSize)return false;
Node* pNode=m_pHashTable[index];
Node* pFind;
if(pNode&&pFind=pNode->Find(key)){
if(pFind==pNode){
pNode=pNode->NextNode();
pFind->Remove();
m_pHashTable[index]=pNode;
}
else pFind->Remove();
delete pFind;
return true;
}
return false;
}
//!删除结点
bool Delete(Node* pNode)
{
int index=Hash::hash(pNode->GetKey())%m_HashSize;
if(index<0&&index>=m_HashSize)return false;
Node* pTemp=m_pHashTable[index];
if(pTemp&&pTemp==pNode){//!避免删除头结点
Node* pNext=pNode->NextNode();
pNode->Remove();
delete pNode;
m_pHashTable[index]=pNext;
return true;
}
else{
pNode->Remove();
delete pNode;
return true;
}
return false;
}
/**查找结点*/
Node* Find(const Key& key)
{
int index=Hash::hash(key)%m_HashSize;
if(index<0&&index>=m_HashSize)return false;
Node* pNode=m_pHashTable[index];
Node* pFind;
if(pNode&&(pFind=pNode->Find(key))){
return pFind;
}
return NULL;
}
/**统计冲突个数*/
void Stat()
{
int count=0;
int times=0;
Node* pNode;
for(int i=0; i<m_HashSize; ++i){
pNode=m_pHashTable[i];
if(pNode){
++count;
count+=pNode->NextNum();
++times;
}
}
printf("collision rate:%f cover rate:%f\n",(count/(double)times),(times/(double)m_HashSize));
}
private:
Node** m_pHashTable;
int m_HashSize;
};
#endif