哈希表(散列表)的基本操作

大家好,近几天没有更新文章,今天在下介绍一个非常使用的哈希表(散列表)



首先要说的是:哈希表又叫散列表(哈希只是英文hash的音译,散列才是标准的翻译) 



好吧,下面是源代码,如果有错误,请见谅!!



//    head.h    //

#include <iostream>
using namespace std;

///哈希表又叫“散列表”(其实音译才叫做哈希)
typedef int keyType;

///元素类型定义
typedef struct 
{
 keyType key;    //关键字
 int hi;               //冲突次数
}DataType;

///散列表类型定义
typedef struct 
{
 DataType *data;
 int tableSize;   //散列表的长度
 int curSize;   //表中关键字的个数
}HashTable;

///构造一个空的哈希表
void CreateHashTable( HashTable *H , int m , int p, int hash[] , int n )
{
 int i, sum, addr, di, k=1;
 (*H).data=(DataType *) malloc ( m*sizeof(DataType) );
 if( !(*H).data )
 {
  cout<<"散列表的信息初始化出错";
  exit(-1);
 }
 for( i=0; i<m; i++ )
 {
  (*H).data[i].key=-1;    //先做一个初始化
  (*H).data[i].hi=0;
 }
 for( i=0; i<n; i++ )
 {
  sum=0;         //冲突的次数
  addr=hash[i]%p;    //注意:这里使用除留余数法求散列函数的地址(当然你可以用别的函数)
  di=addr;
  if( (*H).data[addr].key==-1 )  //这是地址没有冲突的情况
  {
   (*H).data[addr].key=hash[i];      //把数组里的数按照哈希函数放到对应的位置上
   (*H).data[addr].hi=0;
  }
  else    //这是地址有冲突的情况
  {
   do
   {
    di=(di+k)%m;      //遇到冲突往后挪,一直到  key!=-1
    sum+=1;            //采用的是线性探测的方法
   }while(  (*H).data[di].key != -1  );
   (*H).data[di].key=hash[i];
   (*H).data[di].hi=sum;
  }//else
 }//for
 (*H).curSize=n;
 (*H).tableSize=m;
}

///哈希表的打印
void  DisplayHashTable( HashTable H, int m )
{
 int i;
 cout<<"哈希表的地址:"<<endl;
 for( i=0; i<m; i++ )
 {
  cout.width(5);
  cout<<i;
 }
 cout<<"\n关键字:\n";
 for( i=0; i<m; i++ )
 {
  cout.width(5);
  cout<<H.data[i].key;
 }
 cout<<"\n冲突次数:\n";
 for( i=0; i<m; i++ )
 {
  cout.width(5);
  cout<<H.data[i].hi;
 }
 cout<<endl;
}

///在哈希表中查找关键字k
int SearchHash( HashTable H , keyType k )
{
 int d, dl, m ;
 m=H.tableSize;
 d=dl=k%m;       //计算地址
 while( H.data[d].key != -1 )
 {
  if( H.data[d].key==k )
  {
   return d;    //刚好相等就直接返回
  }
  else
  {
   d=(d+1)%m;   //不然的话,继续往后找
  }
  if( d==dl )        //找不到返回-1
   return -1;
 }
 return -1;      //找不到返回-1
}

void HashASL( HashTable H, int m )
{
 float average=0;
 int i;
 for( i=0; i<m; i++ )
 {
  average=average+H.data[i].hi;      //线性探测的计算方法
 }
 average=average/H.curSize;
 cout<<"哈希表的平均查找长度是:"<<average<<endl;
}





///   main.cpp   /

#include "head.h"

void CreateHashTable( HashTable *H , int m , int p, int hash[] , int n );
void  DisplayHashTable( HashTable H, int m );
int SearchHash( HashTable H , keyType k );
void HashASL( HashTable H, int m );

void main()
{
 keyType findKey;
 int pos;
 HashTable H;
 int hash[] = {23, 33, 12, 56, 123, 39, 342, 90};
 int m=11, p=11, n=8;    //说明:m是哈希表的总长度  p是模取的数  n是数组的长度

 CreateHashTable(&H,m,p,hash,n);
 DisplayHashTable(H,m);
 cout<<endl;

 cout<<"输入你想找的关键字";
 cin>>findKey;
 pos=SearchHash(H,findKey);
 if( pos==-1 )
 {
  cout<<"你所查找的关键字不存在"<<endl;
 }
 else
 {
  cout<<"关键字 "<<findKey<<" 在哈希表中的位置是"<<pos<<endl;
 }

 HashASL(H,m);
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值