C++ Hash表设计V1.0

前面发了几篇博客,一个评语都没有,这次废话不多说,直接上代码。有讨论的话再给出代码介绍。请尊重原创!!!

#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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值