哈希表

哈希表的设计主要是设计哈希函数

哈希函数:将关键字映射到哈希表的位置

哈希函数的建立有五种常见方法:

1. 除余法

2.折叠法

3.平方取中法

4.提取法

5. 基数转换法

哈希冲突解决方法

1. 开放定址法

开放定址法又分为线性探查法,二次探查法,双散列函数探查法

2.再哈希法

3.链地址法

4.建立一个公共溢出区

可扩展文件的散列函数

1.可扩展散列

2.线性散列

 

哈希程序示例:

冲突解决方法为:双散列函数探查法

哈希函数关键字为:人名字母ASCII相加

哈希函数为:关键字%M,从而映射到哈希表中的位置

代码:

 

#include<stdio.h>

#include<conio.h>

#define HASH_LEN 50                      //哈希表的长度        

#define M 47                            //随机数

#define NAME_NO 30                      //人名的个数       


typedef struct     

{

char *py;    //名字的拼音

int k;       //拼音所对应的整数

}NAME;

NAME NameList[HASH_LEN];    //全局变量NAME            

typedef struct    //哈希表

{

char *py;   //名字的拼音

int k;      //拼音所对应的整数

int si;     //查找长度

}HASH;

HASH HashList[HASH_LEN];        //全局变量HASH                    

void InitNameList() //姓名(结构体数组)初始化         

{

char *f;

int r,s0,i;

NameList[0].py="wanghui";

NameList[1].py="mayuelong";

NameList[2].py="chenzhicheng";

NameList[3].py="sunpeng";

NameList[4].py="zengqinghui";

NameList[5].py="liqingbo";

NameList[6].py="liujunpeng";

NameList[7].py="jiangquanlei";

NameList[8].py="xingzhengchuan";

NameList[9].py="luzhaoqian";

NameList[10].py="gaowenhu";

NameList[11].py="zhuhaoyin";

NameList[12].py="chenlili";

NameList[13].py="wuyunyun";

NameList[14].py="huangjuanxia";

NameList[15].py="wangyan";

NameList[16].py="zhoutao";

NameList[17].py="jiangzhenyu";

NameList[18].py="liuxiaolong";

NameList[19].py="wangziming";

NameList[20].py="fengjunbo";

NameList[21].py="lilei";

NameList[22].py="wangjia";

NameList[23].py="zhangjianguo";

NameList[24].py="zhuqingqing";

NameList[25].py="huangmin";

NameList[26].py="haoyuhan";

NameList[27].py="zhoutao";

NameList[28].py="zhujiang";

NameList[29].py="lixiaojun";

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

{

   s0=0;

   f=NameList[i].py;

for (r=0;*(f+r)!='\0';r++)

 

s0=*(f+r)+s0;

NameList[i].k=s0;

} }

void CreateHashList() //建立哈希表  

{int i;

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

       {

     HashList[i].py="";

     HashList[i].k=0;

     HashList[i].si=0;

       }

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

       {

     int sum=0;

     int adr=(NameList[i].k)%M; //哈希函数

     int d=adr;

       if(HashList[adr].si==0)     //如果不冲突

          {

       HashList[adr].k=NameList[i].k;

       HashList[adr].py=NameList[i].py;

       HashList[adr].si=1;

          }

       else   //冲突

          {

          do

                {

           d=(d+NameList[i].k%10+1)%M;   //伪随机探测再散列法处理冲突   

           sum=sum+1;   //查找次数加1   

                }while (HashList[d].k!=0);

  

         HashList[d].k=NameList[i].k;

         HashList[d].py=NameList[i].py;

         HashList[d].si=sum+1;

          }}}

void   FindList() //查找   

{

       char name[20]={0};

    int s0=0,r,sum=1,adr,d;

printf("\n请输入姓名的拼音:");    

scanf("%s",name);

for (r=0;r<20;r++)   //求出姓名的拼音所对应的整数(关键字)

   s0+=name[r];

adr=s0%M;   //使用哈希函数

d=adr;

if(HashList[adr].k==s0)          //分3种情况进行判断

   printf("\n姓名:%s   关键字:%d   查找长度为: 1",HashList[d].py,s0);

else if (HashList[adr].k==0)

   printf("无此记录!");

else

{

   int g=0;

   do

   {

    d=(d+s0%10+1)%M;       //伪随机探测再散列法处理冲突                    

    sum=sum+1;

    if (HashList[d].k==0)

    {

     printf("无此记录! ");

     g=1;    

    }

    if (HashList[d].k==s0)

    {   

     printf("\n姓名:%s   关键字:%d   查找长度为:%d",HashList[d].py,s0,sum);

     g=1;

    }

   }while(g==0);  

} }

void   Display() // 显示哈希表      

{int i;

float average=0;

    printf("\n\n地址\t关键字\t\t搜索长度\tH(key)\t 姓名\n"); //显示的格式


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

{

   printf("%d ",i);

   printf("\t%d ",HashList[i].k);

   printf("\t\t%d ",HashList[i].si);

   printf("\t\t%d ",HashList[i].k%M);

   printf("\t %s ",HashList[i].py);

   printf("\n");

}

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

average+=HashList[i].si;

average/=NAME_NO;

printf("\n\n平均查找长度:ASL(%d)=%f \n\n",NAME_NO,average);

}


void main()

{

       char ch1;

printf("\n                           哈希表的建立和查找\n");

   printf("               *-------------------------------------------*\n");

   printf("               |              D. 显示哈希表                |\n");

   printf("               |              F. 查找                      |\n");

   printf("               |              Q. 退出                      |\n");

   printf("               *-------------------------------------------*\n");


InitNameList();                               

CreateHashList ();                       

while(1)

{

printf("\n       Option-:");

fflush(stdin);

    ch1=getchar();

        if (ch1=='D'||ch1=='d')

    Display();  

   else if (ch1=='F'||ch1=='f')

    FindList();

   else if (ch1=='Q'||ch1=='q')

    return;

   else

   {

    printf("\n请输入正确的选择!");

    }}}

 

程序示例2:

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef enum{False,True} BOOL;

typedef enum{NULLKEY,HAVEKEY,DELKEY} HAVEORNOT;

 

typedef struct

{

int elem[MAXSIZE];

HAVEORNOT elemflag[MAXSIZE];

int count;

}HashTable;

typedef struct

{int keynum;

}Record;

void InitialHash(HashTable*);

void CreateHash(HashTable*);

void PrintHash(HashTable);

BOOL SearchHash(HashTable,int,int*);

BOOL InsertHash(HashTable*,Record);

BOOL DeleteHash(HashTable*,Record);

int Hash(int);

 

void main()

{

       HashTable H;

       char ch,j='y';

       int position;

       Record R;

       BOOL temp;

       //textbackground(3);

       //textcolor(15);

       //clrscr();

       InitialHash(&H);

       CreateHash(&H);

      

       printf("This program will show how to operate to a HashTable.\n");

       printf("You can display all elems,search a elem,\ninsert a elem,delete a elem.\n");

      

 

       while(j!='n')

       {

              printf("1.display\n");

              printf("2.search\n");

              printf("3.insert\n");

              printf("4.delete\n");

              printf("5.exit\n");

              scanf(" %c",&ch);

              switch(ch)

              {

              case '1':if(H.count) PrintHash(H);

                     else printf("The HashTable has no elem!\n");

                     break;

              case '2':if(!H.count) printf("The HashTable has no elem!\n");

                     else

                     {printf("Please input the keynum(int) of the elem to search:");

                     scanf("%d",&R.keynum);

                     temp=SearchHash(H,R.keynum,&position);

                    

                     if(temp) printf("The position of the elem is %d\n",position);

                     else printf("The elem isn't exist!\n");

                     }

                     break;

              case '3':if(H.count==MAXSIZE)

                     {printf("The HashTable is full!\n");

                     break;

                     }

                     printf("Please input the elem(int) to insert:");

                     scanf("%d",&R.keynum);

                     temp=InsertHash(&H,R);

                    

                     if(temp) printf("Sucess to insert the elem!\n");

                     else printf("Fail to insert the elem.The same elem has been exist!\n");

                     break;

              case '4':printf("Please input the keynum of the elem(int) to delet:");

                     scanf("%d",&R.keynum);

                     temp=DeleteHash(&H,R);

                    

                     if(temp) printf("Sucess to delete the elem!\n");

                     else printf("The elem isn't exist in the HashTable!\n");

                     break;

              default: j='n';

              }

       }

       printf("The program is over!\nPress any key to shut off the window!\n");

       getchar();

}

 

void InitialHash(HashTable *H)

{

       int i;

       (*H).count=0;

       for(i=0;i<MAXSIZE;i++) (*H).elemflag[i]=NULLKEY;

}

 

void CreateHash(HashTable *H)

{

Record e;

printf("请输入的一系列整数(不超过12个,以-1结束)以建立哈希表:\n");

scanf("%d",&e.keynum);

while(e.keynum!=-1)

    if(InsertHash(H,e))
   scanf("%d",&e.keynum);

    else

      {printf("请输入不重复的数据!");

       return;

       }    

}

 

void PrintHash(HashTable H)

   

       int i;

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

       if(H.elemflag[i]==HAVEKEY)

       printf("%-4d",i);

       printf("\n");

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

       if(H.elemflag[i]==HAVEKEY)

       printf("%-4d",H.elem[i]);

       printf("\ncount:%d\n",H.count);

}

 

BOOL SearchHash(HashTable H,int k,int *p)

{

       int p1;

       p1=(*p)=Hash(k);

       while(H.elemflag[(*p)]==HAVEKEY&&k!=H.elem[(*p)])

      

       {

              (*p)++;

              if((*p)>=MAXSIZE) (*p)=(*p)%MAXSIZE;

              if((*p)==p1) return False;

       }

       if(k==H.elem[(*p)]&&H.elemflag[(*p)]==HAVEKEY)

              return True;

       else return False;

}

 

BOOL InsertHash(HashTable *H,Record e)

{

       int p;

       if(SearchHash((*H),e.keynum,&p))

       return False;

       else

       {(*H).elemflag[p]=HAVEKEY;

       (*H).elem[p]=e.keynum;

       (*H).count++;

       return True;

       }

}

 

BOOL DeleteHash(HashTable *H,Record e)

{

       int p;

       if(!SearchHash((*H),e.keynum,&p))

       return False;

       else

       {(*H).elemflag[p]=DELKEY;

       (*H).count--;

       return True;

       }

}

 

int Hash(int kn)

{

       return (kn%11);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值