hashtable的C++实现,两种解决hash冲突的方法,需要自己提供对Hashedfun的hash函数。
1.分离链地址法(separate chaining)
#include <vector>
#include <list>
using namespace std;
template <typename Hashedfunc>
class HashTable
{
public:
explicit HashTable(int size = 101);
void makeEmpty()
{
for(int i = 0; i < theLists.size(); i++)
theLists[i].clear();
}
bool contains(const Hashedfunc & x) const
{
const list<Hashedfunc> & whichList = theLists[myhash(x)];
return find(whichList.begin(), whichList.end(), x) != whichList.end();
}
bool remove(const Hashedfunc & x)
{
list<Hashedfunc> & whichList = theLists[myhash(x)];
typename list<Hashedfunc>::iterator itr = find(whichList.begin(), whichList.end(), x);
if(itr == whichList.end())
return false;
whichList.erase(itr);
--currentSize;
return true;
}
bool insert(const Hashedfunc & x)
{
list<Hashedfunc> & whichList = theLists[myhash(x)];
if(find(whichList.begin(), whichList.end(), x) != whichList.end())
return false;
whichList.push_back(x);
if(++currentSize > theLists.size())
rehash();
return true;
}
private:
vector<list<Hashedfunc> > theLists; // The array of Lists
int currentSize;
void rehash()
{
vector<list<Hashedfunc> > oldLists = theLists;
// Create new double-sized, empty table
theLists.resize(2 * theLists.size());
for(int j = 0; j < theLists.size(); j++)
theLists[j].clear();
// Copy table over
currentSize = 0;
for(int i = 0; i < oldLists.size(); i++)
{
typename list<Hashedfunc>::iterator itr = oldLists[i].begin();
while(itr != oldLists[i].end())
insert(*itr++);
}
}
int myhash(const Hashedfunc & x) const
{
int hashVal = hash(x);
hashVal %= theLists.size();
if(hashVal < 0)
hashVal += theLists.size();
return hashVal;
}
};
2.探查法(probing hash tables)
template <typename Hashedfunc>
class HashTable
{
public:
explicit HashTable(int size = 101) : array(size)
{
makeEmpty();
}
void makeEmpty()
{
currentSize = 0;
for(int i = 0; i < array.size(); i++)
array[i].info = EMPTY;
}
bool contains(const Hashedfunc & x) const
{
return isActive(findPos(x));
}
bool insert(const Hashedfunc & x)
{
// Insert x as active
int currentPos = findPos(x);
if(isActive(currentPos))
return false;
array[currentPos] = HashEntry(x, ACTIVE);
if(++currentSize > array.size()/2)
rehash();
return true;
}
bool remove(const Hashedfunc & x)
{
int currentPos = findPos(x);
if(!isActive(currentPos))
return false;
array[currentPos].info = DELETED;
return true;
}
enum EntryType { ACTIVE, EMPTY, DELETED };
private:
struct HashEntry
{
Hashedfunc element;
EntryType info;
HashEntry(const Hashedfunc & e = Hashedfunc(), EntryType i = EMPTY )
: element(e), info(i) { }
};
vector<HashEntry> array;
int currentSize;
int findPos(const Hashedfunc & x) const
{
int offset = 1;
int currentPos = myhash(x);
while(array[currentPos].info != EMPTY && array[currentPos].element != x)
{
currentPos += offset; // Compute ith probe
offset += 2;
if(currentPos >= array.size())
currentPos -= array.size();
}
return currentPos;
}
bool isActive(int currentPos) const
{
return array[currentPos].info == ACTIVE;
}
void rehash()
{
vector<HashEntry> oldArray = array;
// Create new double-sized, empty table
array.resize(2*oldArray.size());
for(int j = 0; j < array.size(); j++)
array[j].info = EMPTY;
// Copy table over
currentSize = 0;
for(int i = 0; i < oldArray.size(); i++)
if(oldArray[i].info == ACTIVE)
insert(oldArray[i].element);
}
int myhash(const Hashedfunc & x) const;
};
本文介绍了一种使用C++实现的哈希表,详细解释了两种解决哈希冲突的方法:分离链地址法和探查法。分离链地址法通过在每个桶中维护一个链表来处理冲突,而探查法则在遇到冲突时寻找下一个空位。
581

被折叠的 条评论
为什么被折叠?



