C++ Hash表设计V2.0

在第一个版本上修改完善的,可以任意使用,但请尊重原创:

#ifndef QUICK_HASH_H
#define QUICK_HASH_H
#include 
#include 
/**@file QuickHash.h
 * 实现Hash功能的模板类
 * @author xiaoxing.zhou
 * @date 2012-4-26
 * @version v2.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);
	}
};
templateclass QuickHash;
/**@class
 * 定义Hash链表结点
 * 结点的键值对不负责删除
 */
template
class HashNode
{
public:
	typedef HashNode Node;
	
	HashNode(const Key& key, const Value& value);
	~HashNode();
	
	const Key& GetKey(){return m_key;}
	Value& GetValue(){return m_value;}

	void SetValue(const Value& value){m_value=value;}

protected:
	
	/**前后结点指针操作*/
	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);
	void BackInsert(Node* pNode);
	
	/**结点移除*/
	void Remove();
	
	/**交换结点*/
	void Swap(Node* pNode);
	
	/**链表操作*/
	Node* Find(const Key& key);
	bool Adjacent(Node* pNode);
	int NextNum();
	int PrevNum();

protected:
	Node* m_pPrev;
	Node* m_pNext;

	Key m_key;
	Value m_value;//!要求保存的数据可以复制
	
	template friend class QuickHash;
};
template
HashNode::HashNode(const Key& key, const Value& value)
{
	m_key=key;
	m_value=value;
	m_pPrev=NULL;
	m_pNext=NULL;
}
template
HashNode::~HashNode()
{
	/**前向删除结点*/
	if(m_pPrev)delete m_pPrev;
	/**后向删除结点*/
	if(m_pNext)delete m_pNext;
}
/**前插入结点*/
template
void HashNode::FrontInsert(Node* pNode)
{
	pNode->m_pNext=this;
	pNode->m_pPrev=m_pPrev;
}
/**后插入结点*/
template
void HashNode::BackInsert(Node* pNode)
{
	pNode->m_pNext=m_pNext;
	m_pNext=pNode;
}
/**移除结点*/
template
void HashNode::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;
}
/**交换两个结点顺序*/
template
void HashNode::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;
	}
}
/**遍历链表查找结点*/
template
typename HashNode::Node* HashNode::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;
}
/**判断是否相临*/
template
bool HashNode::Adjacent(Node* pNode)
{
	return pNode->m_pNext==this||pNode->m_pPrev=this;
}
/**后续结点个数*/
template
int HashNode::NextNum()
{
	Node* pTemp=m_pNext;
	int num=0;
	while(pTemp){
		++num;
		pTemp=pTemp->m_pNext;
	}
	return num;
}
/**前驱结点个数*/
template
int HashNode::PrevNum()
{
	Node* pTemp=m_pPrev;
	int num=0; 
	while(pTemp){
		++num;
		pTemp=pTemp->m_pPrev;
	}
	return num;
}
/**@class
 * 定义Hash类
 */
template
class QuickHash
{
public:

	typedef HashNode Node;
	QuickHash();
	~QuickHash();
	
	/**扩大表容量*/
	void Resize(int size);

	/**
	 * 键值对操作
	 * 不阻止插入同键值的结点,使用时候需要注意
	 */
	bool Insert(const Key& key, const Value& value);
	bool Delete(const Key& key, const Value& value);
	bool Delete(Node* pNode);
	
	/**查找键值对*/
	Node* Find(const Key& key);
	
	/**统计信息*/
	void Stat();
	
private:
	Node** m_pHashTable;
	int m_HashSize;
};

template
QuickHash::QuickHash()
{
	m_HashSize=Size;
	m_pHashTable=new Node*[m_HashSize];
	for(int i=0; i
QuickHash::~QuickHash()
{
	for(int i=0; i
void QuickHash::Resize(int size)
{
	if(size>m_HashSize){//!扩大尺寸
		Node** pHashTable=new Node[size];
		Node* pNode;
		Node* pTemp;
		int key;
			
		for(int i=0; iGetKey())%size;
				pTemp=pHashTable[key];
				if(pTemp){
					pTemp->FrontInsert(pNode);
				}
				else pHashTable[key]=pNode;
			}
		}

		delete[] m_pHashTable;
		m_pHashTable=pHashTable;
		m_HashSize=size;
	}
}
//!插入键值对
template
bool QuickHash::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;
}
//!删除键值对
template
bool QuickHash::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;
}
//!删除结点
template
bool QuickHash::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;
}
/**查找结点*/
template
typename QuickHash::Node* QuickHash::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;
}
/**统计冲突个数*/
template
void QuickHash::Stat()
{
	int count=0;
	int times=0;
	Node* pNode;
	for(int i=0; iNextNum();
			++times;
		}
	}
	printf("collision rate:%.2f cover rate:%.2f%%\n",(count/(double)times),(100*times/(double)m_HashSize));
}
#endif



你可能感兴趣的:(数据结构与算法,C/C++)