数据结构与算法——散列表的实现

1、数组的方式实现散列表

1.1头文件

#ifndef _HASHTABLE_H
#define _HASHTABLE_H

enum StateType {Empty, Deleted, Active};
struct HashItem
{
	int data;
	StateType info;
	HashItem()
	{
		info = Empty;
	}
	HashItem(int InputData):data(InputData)
	{
		info = Active;
	}
	bool operator ==(const int& InputData)
	{
		return data == InputData;
	}
	bool operator !=(const int& InputData)
	{
		return data != InputData;
	}
};

class HashTable
{
public:
	HashTable();
	~HashTable();
	HashTable(const int len);
	bool Insert(const int data);
	bool Delete(const int data);
	bool Contain(const int data);
	int  Count();
	void print();
private:
	int Hash(int key);
private:
	int module;
	HashItem *pHash;
	int nCount;
};
#endif //_HASHTABLE_H

1.2 源文件

/*
* Copyright: (c) 2019
*
* 文件名称:  HashTable.cpp	
* 文件标识:
* 摘	要:该散列表不能存放重复数据
*
* 版	本: 1.0
* 作	者: RF_LYF
* 创建日期:	 2019/5/9  22:29
*/

#include "HashTable.h"
#include <iostream>
using namespace std;
HashTable::HashTable()
{
	module = 17;
	pHash = new HashItem[module];
	nCount = 0;
}

HashTable::HashTable(const int len):module(len)
{
	pHash = new HashItem[module];
	nCount = 0;
}

HashTable::~HashTable()
{
	delete []pHash;
	pHash = NULL;
}

/**
* @brief
*
* @method:    Insert
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  10:38 
*/
bool HashTable::Insert(const int data)
{
	if(nCount == module)
		return false;
	else
	{
		nCount++;
		int index = Hash(data);
		while(pHash[index].info != Empty && pHash[index].info != Deleted)
		{
			index = Hash(index + 1);
		}
		pHash[index] = data;
		return true;
	}
}

/**
* @brief
*
* @method:    Delete
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  10:38 
*/
bool HashTable::Delete(const int data)
{
	int index = Hash(data);
	while(pHash[index] != data)
	{
		index = Hash(index + 1);
		if(pHash[index].info == Empty || index == Hash(data))
			return false;//数据不存在
	}
	pHash[index].info = Deleted;
	nCount--;
	return true;
}

/**
* @brief
*
* @method:    Count
* @access:    public 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  10:20 
*/
int  HashTable::Count()
{
	return nCount;
}

/**
* @brief
*
* @method:    Contain
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  10:25 
*/
bool HashTable::Contain(const int data)
{
	if(pHash[Hash(data)] == data)
		return true;
	else
	{
		int index = Hash(data);
		while(pHash[index] != data)
		{
			index = Hash(index + 1);
			if(pHash[index].info == Empty || index == Hash(data))
				return false;
		}
		return true;
	}
}


/**
* @brief      除留法
*
* @method:    Hash
* @access:    private 
* @param:     int key
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  10:11 
*/
int HashTable::Hash(int key)
{
	return key % module;
}


/**
* @brief	  用来测试程序
*
* @method:    print
* @access:    public
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/10  14:24 
*/
void HashTable::print()
{
	for(int i = 0; i < module; ++i)
	{
		if(pHash[i].info != Empty && pHash[i].info != Deleted)
			cout << pHash[i].data << endl;
	}
}

2、链表的方式实现散列表

2.1 头文件

#ifndef _HASHTABLELIST_H
#define _HASHTABLELIST_H
#include <list>
enum StateType {Empty, Deleted, Active};
struct HashItem
{
	int data;
	StateType info;
	HashItem()
	{
		info = Empty;
	}
	HashItem(const int& InputData)
	{
		data = InputData;
		info = Active;
	}
};
class HashTableList
{
public:
	HashTableList(void);
	HashTableList(int nLen);
	~HashTableList(void);
	bool Insert(const int& data);
	bool Delete(const int& data);
	bool Contain(const int& data);
	int Count();
	void print();
private:
	int Hash(int key);
	void erase();
	
	typedef std::list<HashItem>* NodeType;
private:
	int module;
	NodeType *pHeadArr;
	int nCount;
};

#endif // _HASHTABLELIST_H

2.2 源文件

#include "HashTableList.h"
#include <iostream>
#include <string.h>
using namespace std;

HashTableList::HashTableList(void)
{
	module = 17;
	nCount = 0;
	pHeadArr = new NodeType[module];
	memset((void *)pHeadArr, 0, module*sizeof(NodeType));
}


HashTableList::~HashTableList(void)
{
	erase();
}


HashTableList::HashTableList(int nLen):module(nLen)
{
	nCount = 0;
	pHeadArr = new NodeType[module];
	memset((void *)pHeadArr, 0, module*sizeof(NodeType));
}


/**
* @brief
*
* @method:    Insert
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  11:51 
*/
bool HashTableList::Insert(const int& data)
{
	int index = Hash(data);
	if(pHeadArr[index] == NULL)
	{
		pHeadArr[index] = new list<HashItem>();
	}
	HashItem *pTemp = new HashItem(data);
	pHeadArr[index]->push_back(*pTemp);
	delete pTemp;
	++nCount;
	return true;
}


/**
* @brief
*
* @method:    Delete
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  12:03 
*/
bool HashTableList::Delete(const int& data)
{
	if(pHeadArr[Hash(data)] == NULL)
		return false;
	else
	{
		int index = Hash(data);
		list<HashItem>::iterator it = pHeadArr[index]->begin();
		for(; it != pHeadArr[index]->end(); ++it)
		{
			if(it->data == data)
			{
				pHeadArr[index]->erase(it);
				--nCount;
				return true;
			}
		}
		return false;
	}
}


/**
* @brief
*
* @method:    Contain
* @access:    public 
* @param:     int data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/10  11:58 
*/
bool HashTableList::Contain(const int& data)
{
	if(pHeadArr[Hash(data)] == NULL)
		return false;
	else
	{
		int index = Hash(data);
		list<HashItem>::iterator it = pHeadArr[index]->begin();
		for(; it != pHeadArr[index]->end(); ++it)
		{
			if(it->data == data)
				return true;
		}
		return false;
	}
}


/**
* @brief
*
* @method:    Count
* @access:    public 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  11:25 
*/
int HashTableList::Count()
{
	return nCount;
}


/**
* @brief
*
* @method:    Hash
* @access:    private 
* @param:     int key
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  11:27 
*/
int HashTableList::Hash(int key)
{
	return key % module;
}


/**
* @brief
*
* @method:    erase
* @access:    private 
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/10  13:48 
*/
void HashTableList::erase()
{
	for(int i = 0; i < module; ++i)
	{
		if(pHeadArr[i] != NULL)
		{
			delete pHeadArr[i];
			pHeadArr[i] = NULL;
		}
	}
	delete []pHeadArr;
	pHeadArr = NULL;
}


void HashTableList::print()
{
	for(int i = 0; i < module; ++i)
	{
 		if(pHeadArr[i] != NULL)
 		{
 			list<HashItem>::iterator it = pHeadArr[i]->begin();
 			for(; it != pHeadArr[i]->end(); ++it)
 				cout << it->data << " ";
 		}
		cout << endl;
	}
}

3、支持动态扩容的散列表——数组方式实现

3.1 头文件

/*
* Copyright: (c) 2019
*
* 文件名称:  HashTableOpti.h	
* 文件标识:
* 摘	要:
*
* 版	本: 1.0
* 作	者: RF_LYF
* 创建日期:	 2019/5/10  16:36
*/

#ifndef _HASHTABLEOPTI_H
#define _HASHTABLEOPTI_H
enum StateType {Empty, Active, Deleted};
struct HashItem
{
	int data;
	StateType info;
	HashItem()
	{
		info = Empty;
	}
	HashItem(const int& InputData)
	{
		data = InputData;
		info = Active;
	}
	bool operator == (const int& InputData)
	{
		return data == InputData;
	}
	bool operator != (const int& InputData)
	{
		return data != InputData;
	}
};
class HashTableOpti
{
public:
	HashTableOpti(void);
	HashTableOpti(const int& nLen, const double& f);
	~HashTableOpti(void);

	bool Insert(const int& data);
	bool Delete(const int& data);
	bool Contain(const int& data);
	int Count();
	void print();
private:
	int Hash(int key, int mod);
	void Expand();
	bool ArrEmpty();
	int Find(const int& data, bool& inOldArr);
	void InsertAssist(const int &data);
	int FindValidDataInOldArr();
private:
	int module;
	int moduleOld;
	int nCount;
	int nCountOld;
	HashItem* pHash;
	HashItem* pHashOld;
	double factor;
};

#endif //_HASHTABLEOPTI_H

3.2 源文件

#include "HashTableOpti.h"
#include <iostream>
using namespace std;

HashTableOpti::HashTableOpti(void)
{
	module = 17;
	moduleOld = 0;
	nCount = 0;
	nCountOld = 0;
	pHash = new HashItem[module];
	pHashOld = NULL;
	factor = 0.75;
}


HashTableOpti::HashTableOpti(const int& nLen, const double& f):
module(nLen), factor(f)
{
	moduleOld = 0;
	nCount = 0;
	nCountOld = 0;
	pHash = new HashItem[module];
	pHashOld = NULL;
}


HashTableOpti::~HashTableOpti(void)
{
	delete []pHash;
	pHash = NULL;
	if(pHashOld != NULL)
	{
		delete []pHashOld;
		pHashOld = NULL;
	}
}


/**
* @brief
*
* @method:    Insert
* @access:    public 
* @param:     const int & data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/20  11:27 
*/
bool HashTableOpti::Insert(const int& data)
{
	double ret = (double)nCount / module;
	if(ret >= factor)
	{
		Expand();
	}
	int temp = FindValidDataInOldArr();
	if(temp >= 0)
	{
		InsertAssist(pHashOld[temp].data);
		ArrEmpty();
	}
	InsertAssist(data);
	return true;
}


/**
* @brief
*
* @method:    FindValidDataInOldArr
* @access:    private 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/20  14:37 
*/
int HashTableOpti::FindValidDataInOldArr()
{
	if(pHashOld == NULL)
		return -1;
	else
	{
		for(int i = 0; i < moduleOld; ++i)
		{
			if(pHashOld[i].info != Empty && pHashOld[i].info != Deleted)
			{
				pHashOld[i].info = Deleted;
				return i;
			}
		}
		return -1;
	}
}


/**
* @brief
*
* @method:    InsertAssist
* @access:    private 
* @param:     const int & data
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/20  14:39 
*/
void HashTableOpti::InsertAssist(const int &data)
{
	int index = Hash(data, module);
	while(pHash[index].info != Empty && pHash[index].info != Deleted)
	{
		index = index + 1;
	}
	pHash[index].data = data;
	pHash[index].info = Active;
	nCount++;
}


/**
* @brief
*
* @method:    ArrEmpty
* @access:    private 
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/20  12:02 
*/
bool HashTableOpti::ArrEmpty()
{
	if(--nCountOld == 0)
	{
		delete []pHashOld;
		pHashOld = NULL;
		return true;
	}
	return false;
}


/**
* @brief
*
* @method:    Find
* @access:    private 
* @param:     const int & data
* @param:     bool & inOldArr
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/20  12:03 
*/
int HashTableOpti::Find(const int& data, bool& inOldArr)
{
	int nFlag = -1;
	if(pHashOld)
	{
		int index = Hash(data, moduleOld);
		while(pHashOld[index].info != Empty)
		{
			if(pHashOld[index] == data)
			{
				nFlag = index;
				inOldArr = true;
				break;
			}
			index = index + 1;
		}
	}
	if(nFlag < 0)
	{
		int index = Hash(data, module);
		while(pHash[index].info != Empty)
		{
			if(pHash[index] == data)
			{
				nFlag = index;
				inOldArr = false;
				break;
			}
			index = index + 1;
		}
		return nFlag;
	}
	else
	{
		return nFlag;
	}	
}


/**
* @brief
*
* @method:    Delete
* @access:    public 
* @param:     const int & data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/20  13:41 
*/
bool HashTableOpti::Delete(const int& data)
{
	bool bFlag = false;
	int ret = Find(data, bFlag);
	if(ret >= 0 && bFlag)
	{
		pHashOld[ret].info = Deleted;
		ArrEmpty();
		return true;		
	}
	else if(ret >= 0 && !bFlag)
	{
		pHash[ret].info = Deleted;
		--nCount;
		return true;
	}
	else
		return false;
}


/**
* @brief
*
* @method:    Contain
* @access:    public 
* @param:     const int & data
* @Return:    bool
* @author:    RF_LYF
* @since:   2019/5/20  14:39 
*/
bool HashTableOpti::Contain(const int& data)
{
	bool bFlag = false;
	int ret = Find(data, bFlag);
	if(ret < 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}


/**
* @brief
*
* @method:    Count
* @access:    public 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  16:53 
*/
int HashTableOpti::Count()
{
	return nCount + nCountOld;
}


void HashTableOpti::print()
{
	if(pHashOld)
	{
		cout << "member in Old Array is :" << endl;
		for(int i = 0; i < moduleOld; ++i)
		{
			if(pHashOld[i].info != Empty && pHashOld[i].info != Deleted)
			cout << pHashOld[i].data << " ";
		}
		cout << endl;
	}
	cout << "member in Current Array is :" << endl;
	for(int i = 0; i < module; ++i)
	{
		if(pHash[i].info != Empty && pHash[i].info != Deleted)
			cout << pHash[i].data << " ";
	}
	cout << endl;
}


/**
* @brief
*
* @method:    Hash
* @access:    private 
* @param:     int key
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/10  17:14 
*/
int HashTableOpti::Hash(int key, int mod)
{
	return key % mod;
}


/**
* @brief
*
* @method:    Expand
* @access:    private 
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/20  14:46 
*/
void HashTableOpti::Expand()
{
	moduleOld = module;
	module *= 2;
	pHashOld = pHash;
	nCountOld = nCount;
	nCount = 0;
	pHash = new HashItem[module];
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值