哈希表
来源:互联网 发布:怎么激活电脑windows 编辑:程序博客网 时间:2024/04/30 08:41
#ifndef _HASH_
#define _HASH_
#include "chainnode.h"
//线性开型寻址散列
//当要插入一个元素时,可以连续地检查散列表的个各项,直到找到一个空槽来放置这个元素为止。
//检查顺序可以是线性的,可以是二次的,也可以是再次散列的。
//容量空间有限制
template<class T> class CLinearityHashTable
{
public:
CLinearityHashTable(int divisor = 10);
~CLinearityHashTable();
template<class T> friend ostream& operator<<(ostream &os,const CLinearityHashTable<T>& queue);
public:
int divisor;
T *ht;
bool *bempty;
};
template<class T> CLinearityHashTable<T>::CLinearityHashTable(int divisor)
{
this->divisor = divisor;
this->ht = new T[divisor];
assert(ht!=NULL);
this->bempty = new bool[divisor];
assert(bempty != NULL);
for (int index=0; index<divisor; index++)
{
bempty[index] = false;
}
}
template<class T> CLinearityHashTable<T>::~CLinearityHashTable()
{
if (ht != NULL)
{
delete [] ht;
ht = NULL;
}
if (bempty != NULL)
{
delete [] bempty;
bempty = NULL;
}
}
template<class T> ostream& operator<<(ostream &os,const CLinearityHashTable<T>& linearity)
{
for (int index=0; index<linearity.divisor; index++)
{
if (linearity.bempty[index])
{
cout<<linearity.ht[index]<<" ";
}
else
{
cout<<"_ ";
}
}
cout<<endl;
return os;
}
//链式哈希表
//通过链表处理,空间可以自动增加
template<class T> class CLinkListHashTable
{
public:
CLinkListHashTable(int divisor = 10);
~CLinkListHashTable();
template<class T> friend ostream& operator<<(ostream &os,const CLinkListHashTable<T>& queue);
public:
int divisor;
ChainNode<T> **head;
};
template<class T> CLinkListHashTable<T>::CLinkListHashTable(int divisor)
{
this->divisor = divisor;
this->head = new ChainNode<T>*[divisor];
for (int index=0; index<divisor; index++)
{
this->head[index] = new ChainNode<T>(index);
this->head[index]->next = new ChainNode<T>(INT_MAX);
}
}
template<class T> CLinkListHashTable<T>::~CLinkListHashTable()
{
ChainNode<T> *p = NULL;
for (int index=0; index<divisor; index++)
{
if (this->head[index] != NULL)
{
while (this->head[index] != NULL)
{
p = this->head[index]->next;
delete this->head[index];
this->head[index] = p;
}
}
}
delete[] head;
}
template<class T> ostream& operator<<(ostream &os,const CLinkListHashTable<T>& linklist)
{
ChainNode<T> *p = NULL;
for (int index=0; index<linklist.divisor; index++)
{
if (linklist.head[index] != NULL)
{
p = linklist.head[index];
while (p != NULL)
{
if (p->data == INT_MAX)
{
cout<<"NULL"<<"/t";
}
else
{
cout<<p->data<<"/t";
}
p = p->next;
}
}
cout<<endl;
}
cout<<endl;
return os;
}
#endif
#include <iostream>
#include <assert.h>
#include "hash.h"
using namespace std;
template<class T> class CHashTable
{
private :
CHashTable(int div)// 必须定义, 且为private.
{
cLinearityHT = new CLinearityHashTable<T>(div);
cLinkListHT = new CLinkListHashTable<T>(div);
}
CHashTable(const CHashTable&); // 不实现.
CHashTable& operator=(const CHashTable&); // 不实现.
~CHashTable() // 可声明为public, 但这里声明为private没有错, 可被调用.
{
delete cLinearityHT;
delete cLinkListHT;
}
public :
static CHashTable& GetInstance(int div)
{
static CHashTable theSingleton(div);
return theSingleton;
}
private:
CLinearityHashTable<T> *cLinearityHT;
CLinkListHashTable<T> *cLinkListHT;
public :
//线性开型寻址,使用数组,缺点空间容易溢出
//构建HASHTABLE,
void createLinearityHashTable(T* data, int n);
//添加元素
void insertLinearityHashTable(T data);
//删除元素
void delLinearityHashTable(T data);
//链表散列寻址,使用链表,不仅不会出现空间溢出现象,而且还可以排序
//构建
void createLinkListHashTable(T* data, int n);
//添加元素
void insertLinkListHashTable(T data);
//删除元素
void delLinkListHashTable(T data);
//LZW算法中,首先建立一个字符串表,把每一个第一次出现的字符串放入串表中,
//并用一个数字来表示,这个数字与此字符串在串表中的位置有关,并将这个数字存入压缩文件中,
//如果这个字符串再次出现时,即可用表示它的数字来代替,并将这个数字存入文件中。
void lzw_compress(T* data, int n)
{
}
void lzw_decompress()
{
}
private:
};
template<class T> void CHashTable<T>::createLinearityHashTable(T* data, int n)
{
assert(data != NULL, "invalid parameter in createLinearityHashTable, data==NULL");
assert(n<cLinearityHT->divisor, "invalid parameter in createLinearityHashTable, n>div");
for (int index=0; index<n; index++)
{
insertLinearityHashTable(data[index]);
}
}
template<class T> void CHashTable<T>::insertLinearityHashTable(T data)
{
int pos = data%cLinearityHT->divisor;
if (cLinearityHT->bempty[pos])
{
int nextpos = (pos+1)%cLinearityHT->divisor;
while (cLinearityHT->bempty[nextpos] && nextpos != pos)
{
nextpos = (nextpos+1)%cLinearityHT->divisor;
}
assert(nextpos != pos, "no memory");
pos = nextpos;
}
cLinearityHT->ht[pos] = data;
cLinearityHT->bempty[pos] = true;
cout<<*cLinearityHT<<endl;
}
template<class T> void CHashTable<T>::delLinearityHashTable(T data)
{
int curpos = 0;
if (cLinearityHT->ht[curpos] != data)
{
int nextpos = (curpos+1)%cLinearityHT->divisor;
while (cLinearityHT->ht[nextpos] != data &&
nextpos != curpos)
{
nextpos = (nextpos+1)%cLinearityHT->divisor;
}
if (nextpos == curpos)
{
return;
}
curpos = nextpos;
}
int nextpos = (curpos+1)%cLinearityHT->divisor;
while (cLinearityHT->bempty[nextpos] && nextpos != curpos)
{
nextpos = (nextpos+1)%cLinearityHT->divisor;
}
nextpos = (nextpos-1+cLinearityHT->divisor)%cLinearityHT->divisor;
if (nextpos == curpos)
{
nextpos = (curpos-1+cLinearityHT->divisor)%cLinearityHT->divisor;
}
for (int index=curpos; index!=nextpos;)
{
cLinearityHT->ht[index] = cLinearityHT->ht[(index+1)%cLinearityHT->divisor];
index = (index+1)%cLinearityHT->divisor;
}
cLinearityHT->bempty[nextpos] = false;
cout<<*cLinearityHT<<endl;
}
template<class T> void CHashTable<T>::createLinkListHashTable(T* data, int n)
{
assert(data != NULL, "invalid parameter in createLinkListHashTable, data==NULL");
assert(n<cLinkListHT->divisor, "invalid parameter in createLinkListHashTable, n>div");
for (int index=0; index<n; index++)
{
insertLinkListHashTable(data[index]);
}
}
template<class T> void CHashTable<T>::insertLinkListHashTable(T data)
{
int pos = data%cLinkListHT->divisor;
if (cLinkListHT->head[pos] != NULL)
{
ChainNode<T> *p = cLinkListHT->head[pos]->next;
ChainNode<T> *q = NULL;
ChainNode<T> *pnode = new ChainNode<T>(data);
if (data < p->data)
{
cLinkListHT->head[pos]->next = pnode;
pnode->next = p;
}
else
{
q = p;
p = p->next;
while(p!=NULL && data > p->data)
{
q = p;
p = p->next;
}
assert(p != NULL, "insert data invalid");
q->next = pnode;
pnode->next = p;
}
}
cout<<*cLinkListHT<<endl;
}
template<class T> void CHashTable<T>::delLinkListHashTable(T data)
{
ChainNode<T> *p = NULL;
ChainNode<T> *q = NULL;
for (int index=0; index<cLinkListHT->divisor; index++)
{
q = cLinkListHT->head[index];
p = cLinkListHT->head[index]->next;
while(p != NULL && p->data != data)
{
q = p;
p = p->next;
}
if (p != NULL)
{
q->next = p->next;
delete p;
}
}
cout<<*cLinkListHT<<endl;
}