哈希表

来源:互联网 发布:怎么激活电脑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;
}

原创粉丝点击