仿照标准库做了个hashmap!不容易啊。

// ConsoleTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
const int primes[] = {2009,3009,4009,5009,6009,7009,8009,16009};

template<class T>
int hash(T t){return t.hashCode();}


template <class KeyT,class ValT>
struct  MyPair
{
	typedef KeyT TypeKey;
	typedef ValT TypeVal;
	KeyT key;
	ValT value;
};

template <class Pair>
struct BucketNode
{
	typedef Pair DataType;
	Pair PairValue;
	BucketNode* pNext;
};

template <class DataType>
struct Bucket
{
	typedef DataType Pair ;
	typedef BucketNode<Pair> NodeType;
	BucketNode<Pair>* pHead;
};

template<class Bucket>
class HashMap
{
public:
	typedef  typename Bucket::Pair MapPairType;
	typedef  typename  MapPairType::TypeKey KeyT;
	typedef  typename  MapPairType::TypeVal ValT;
	HashMap();
	const  typename  MapPairType* GetValue(KeyT key);
	void insert(MapPairType data);
	void rehash();
	unsigned int HashValue(unsigned int hashCode);
	float fHashFacil;  
	int nContOfContent;
	int indexCapbility;
	Bucket** pContent;
};

template<class Bucket>
const typename HashMap<Bucket>::MapPairType* HashMap<Bucket>::GetValue(KeyT key)
{
	int indexOfFind = HashValue(hash(key));

	Bucket::NodeType* pNode = pContent[indexOfFind]->pHead;
	while (pNode != NULL)
	{
		if (pNode->PairValue.key == key)
		{
			return &(pNode->PairValue);
		}
		else
		{
			pNode = pNode->pNext;
		}
	}
	return NULL;
}

template<class Bucket>
void HashMap<Bucket>::rehash()
{	
	Bucket** oldContent =  pContent;
	int oldIndexCapbility = indexCapbility;

	if (indexCapbility >= sizeof(primes)/sizeof(primes[0]) - 1)
	{
		return;
	}
	while ((int)(fHashFacil*primes[indexCapbility]) < nContOfContent)
	{
		if (indexCapbility >= sizeof(primes)/sizeof(primes[0]) - 1)
		{
			break;
		}
		indexCapbility ++;
	}
	//
	//Rehash the table.
	//

	//Reset the Count to zero.
	nContOfContent = 0;

	//Insert old data to new table;
	pContent = new Bucket* [primes[indexCapbility]];
	memset(pContent, 0, primes[indexCapbility]*sizeof(Bucket*));
	for (int i = 0; i<primes[oldIndexCapbility]; i ++)
	{
		if (oldContent[i] != NULL)
		{
			Bucket::NodeType* pNode = oldContent[i]->pHead;
			while (pNode)
			{
				insert(pNode->PairValue);
				Bucket::NodeType* oldNode = pNode;
				pNode = pNode->pNext;
				delete oldNode;
			}
		}
	}
	delete[] oldContent;
}
template<class Bucket>
void HashMap<Bucket>::insert(MapPairType  data)
{
	if ((int)(fHashFacil*primes[indexCapbility]) < nContOfContent)
	{
		//std::cout<<"The current conten is "<<mapHash.nContOfContent<<std::endl;
		std::cout<<"Rehash:The current capbility is"<<primes[indexCapbility]<<std::endl;
		std::cout<<"Rehash:The current count is"<<nContOfContent<<std::endl;
		rehash();
	}
	int hashVal = HashValue(hash(data.key));
	std::cout<<hashVal<<"\t"<<data.key.m_strValue.data()<<"\t"<<data.value<<std::endl;
	if (pContent[hashVal] == NULL)
	{
		Bucket* pBucket = new Bucket;
		pBucket->pHead = new Bucket::NodeType;
		pBucket->pHead->PairValue = data;
		pBucket->pHead->pNext = NULL;
		pContent[hashVal] = pBucket;
		//delete pBucket;
	}
	else
	{
		Bucket::NodeType* pNode = pContent[hashVal]->pHead;
		while (pNode->pNext!= NULL)
		{
			pNode = pNode->pNext;
		}
		Bucket* pBucket = new Bucket;
		pNode->pNext = new Bucket::NodeType;
		pNode->pNext->pNext = NULL;
		pNode->pNext->PairValue = data;
	}
	nContOfContent ++;
}

template<class Bucket>
HashMap<Bucket>::HashMap()
{
	fHashFacil = 0.75;
	indexCapbility = 0;
	nContOfContent = 0;
	pContent = NULL;
	pContent = new Bucket* [primes[indexCapbility]];
	memset(pContent, 0, primes[indexCapbility]*sizeof(Bucket*));
}

template<class Bucket>
unsigned int HashMap<Bucket>::HashValue(unsigned int hashCode)
{
	return hashCode%(primes[indexCapbility]);
}



//下面是测试程序。
//作为hashmap的(key,value)对中key必须定义==操作符和HashCode方法。
class HashString
{
	friend bool operator== (const HashString& keyLeft, const HashString& keyRight);
public:
	HashString(const std::string& strValue)
	{
		m_strValue = strValue;
	}
	HashString()
	{
		m_strValue = ("");
	}
	operator std::string()
	{
		return m_strValue;
	}
	int hashCode()
	{
		register unsigned int h;
		register unsigned char *p; 

		for(h=0, p = (unsigned char *)m_strValue.data(); *p ; p++)
			h = 31 * h + *p; 

		return h;
	}
	std::string m_strValue;
};

bool operator== (const HashString& keyLeft, const HashString& keyRight)
{
	return keyLeft.m_strValue == keyRight.m_strValue;
}

int _tmain(int argc, _TCHAR* argv[])
{
	HashMap<Bucket<MyPair<HashString, unsigned int>>> mapHash;

	for(int i = 0; i< 1000; i++)
	{
		MyPair<HashString, unsigned int> pairValue1;
		std::string strValue("XiongBei");
		char buffer[33];
		_itoa_s(i,buffer,33,10);
		pairValue1.key = strValue.append(buffer);
		pairValue1.value = i;
		mapHash.insert(pairValue1);
	}
	//std::cout<<"The current conten is "<<mapHash.nContOfContent<<std::endl;
	std::cout<<"The current capbility is"<<primes[mapHash.indexCapbility]<<std::endl;
	std::cout<<"The current count is"<<mapHash.nContOfContent<<std::endl;
	return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值