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];
}