哈希表设计

【问题描述】

     研究哈希(HAXI)表查找技术的两个重要问题是:构造HAXI函数和处理冲突。现在要求针对某个数据集合中的关键字设计一个哈希表(选择合适的哈希函数 和处理冲突的方法),完成HAXI表的建立、查找,并计算HAXI表查找成功的平均查找长度。HAXI函数的构造方法有多种,其中除留余数法是一种最简单 和最常用的方法。

考虑具体问题的关键字集合,如{19,14,23,1,68,20,84,27,55,11,10,79}这样一组数据和给定的哈希表长m 或哈希表的装填因子a,选用除留余数法和线性探测再散列技术解决冲突所形成的哈希表以及该哈希表在查找成功时的平均查找长度ASL。

【数据描述】

HAXI表是根据设定的HAXI函数和处理冲突的方法将一组关键字映射到一个有限的连续的地址区间上,并以关键字在地址区间的“象”作为记录在表中的存储位置。因此我们可以采用动态分配的顺序存储结构表示HAXI表。

typedef struct {

    KeyType key ;



}ElemType;      //元素类型的定义

ElemType  *HAXI;//动态分配的哈希表的首地址

【算法描述】

step1:选择合适的哈希函数H( key)=key % p(P为小于或等于HAXI 表长的最大质数);

step2:计算各个关键字的直接哈希函数值;

step3:根据处理冲突的方法建立哈希表,并输出;

step4:在哈希表中进行查找,输出查找的结果,以及所需和记录关键字比较的次数,并计算和输出在等概率情况下查找成功的平均查找长度。

【C源程序】

#include <stdlib.h>

#include <stdio.h>

#define NULL 0

typedef int KeyType;

typedef struct {

    KeyType key ;



}ElemType;

int haxi(KeyType key,int m){

/*根据哈希表长m, 构造除留余数法的哈希函数haxi*/

  int i,p,flag;

  for (p=m ; p>=2  ; p--)          /*p为不超过m的最大素数*/

    { for (i=2,flag=1;i<=p/2 &&flag;i++)

         if (p %i==0) flag=0;

      if (flag==1) break;

     }

return  key%p;                   /*哈希函数*/

}

void inputdata(ElemType **ST,int n ){

/*从键盘输入n个数据,存入数据表ST(采用动态分配的数组空间)*/

  KeyType key;

  int i;

  (*ST)=(ElemType*)malloc(n*sizeof(ElemType));

  printf("/nPlease input %d data:",n);

  for (i=0;i<n;i++)

     scanf("%d",&((*ST)[i].key));

}

void createhaxi(ElemType **HAXI,ElemType *ST,int n,int m){

  /*根据数据表ST,构造哈希表HAXI*,n,m分别为数据集合ST和哈希表的长度*/

int i,j;

  (*HAXI)=(ElemType*)malloc(m*sizeof(ElemType));

  for (i=0;i<m;i++) (*HAXI)[i].key=NULL;  /*初始化哈希为空表(以0表示空)*/

  for (i=0;i<n;i++){

  j=haxi(ST[i].key,m);                   /*获得直接哈希地址*/

    while ((*HAXI)[j].key!=NULL) j=(j+1)%m;/*用线性探测再散列技术确定存放位置*/

    (*HAXI)[j].key=ST[i].key;              /*将元素存入哈希表的相应位置*/

  }

}

int search(ElemType *HAXI,KeyType key,int m,int *time){

  /*在表长为m的哈希表中查找关键字等于key的元素,并用 time记录比较次数,

   若查找成功,函数返回值为其在哈希表中的位置,否则返回-1*/

int i;

  *time=1;

  i=haxi(key,m);

  while (HAXI[i].key!=0 && HAXI[i].key!=key) {i++; ++*time;}

  if (HAXI[i].key==0) return -1;

  else return i;

}

main(){

  ElemType *ST,*HAXI;

  KeyType key;

  int i,n,m,stime,time;

  char ch;

  printf("/nPlease input n && m(n<=m)");    /*输入关键字集合元素个数和HAXI表长*/

  scanf("%d%d",&n,&m);

  inputdata(&ST,n);                        /*调用函数,输入n个数据*/

  createhaxi(&HAXI,ST,n,m);                /*建立哈希表*/

/*输出已建立的哈希表*/

  printf("/nThe haxi Table is/n");   

  for (i=0;i<m;i++) printf("%5d",i);

  printf("/n");

  for (i=0;i<m;i++) printf("%5d",HAXI[i].key);

  /*哈希表的查找,可进行多次查找*/

do {

       printf("/nInput the key you want to search:");

       scanf("%d",&key);

       i=search(HAXI,key,m,&time);

       if (i!=-1) {printf("/nSuccess,the position is %d ",i);/*查找成功*/

           printf("/nThe time of compare is %d",time);

          }

       else{ printf("/nUnsuccess");                 /*查找失败*/

    printf("/nThe time of compare is %d",time);

          }

       printf("/nContinue(y/n):/n");                /*是否继续查找yes or no*/

       ch=getch();

       }

while (ch=='y' || ch=='Y') ;    

/*计算表在等概率情况下的平均查找长度,并输出*/

     for (stime=0,i=0;i<n;i++) {

       search(HAXI,ST[i].key,m,&time);

       stime+=time;

    };

    printf("/nThe Average Search Length is%5.2f",(float)stime/n);

    ch=getch();

}

【测试数据】

1.     按运行提示输入数据(关键字集合)ST,建立HAXI表,然后进行多次查找。

Please input n && m(n<=m):12  15

19 14 23 01 68 20 84 27 55 11 10 79

The haxi Table is:

0  1    2    3    4   5   6   7   8   9   10   11  12   13   14

14    1   68  27  55  19  20  84  79  23   11  10

Input the key you want to search:27

Success,the position is 4

The time of compare is 4;

Continue(y/n):y

Input the key you want to search:68

Success,the position is 3

The time of compare is 1;

Continue(y/n):n

The Average Search Length is 2.5

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值