哈希表应用实例

转自:http://blog.csdn.net/zouchunlaigo1988/article/details/7163920

1:问题描述

        针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。

2:基本要求

          假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用伪随机探测再散列发处理冲突。

3:数据结构设计

[cpp]  view plain  copy
  1. #ifndef _HashTest_H_  
  2. #define _HashTest_H_  
  3.   
  4. #define NAME_NO 30  
  5. #define HASH_LENGTH 50  
  6. #define M 50;  
  7.   
  8. typedef struct        
  9. {     
[cpp]  view plain  copy
  1. char *py;      //名字的拼音  
[cpp]  view plain  copy
  1.     int k;         //拼音所对应的整数  
  2. }NAME;  
  3.   
  4. typedef struct         //哈希表  
  5. {     
  6.     char *py;     //名字的拼音  
  7.     int k;        //拼音所对应的整数  
[cpp]  view plain  copy
  1.     int si;       //查找长度  
  2. }HASH;  
  3.   
  4. #endif   

4:主要算法设计

(1)姓名(结构体数组)初始化

   名字以拼音的形式够成字符串,将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字。

[cpp]  view plain  copy
  1. void InitNameList()            
  2. {     
  3.     char *f;  
  4.     int r,s0,i;  
  5.     NameList[0].py="chenliang";//陈亮  
  6.     NameList[1].py="chenyuanhao";//陈元浩  
  7.     NameList[2].py="chengwenliang";//程文亮  
  8.     NameList[3].py="dinglei";//丁磊  
  9.     NameList[4].py="fenghanzao";//冯汉枣  
  10.     NameList[5].py="fuzongkai";//付宗楷  
  11.     NameList[6].py="hujingbin";//胡劲斌  
  12.     NameList[7].py="huangjianwu";//黄建武  
  13.     NameList[8].py="lailaifa";//赖来发  
  14.     NameList[9].py="lijiahao";//李嘉豪  
  15.     NameList[10].py="liangxiaocong";//梁晓聪  
  16.     NameList[11].py="linchunhua";//林春华  
  17.     NameList[12].py="liujianhui";//刘建辉  
  18.     NameList[13].py="luzhijian";//卢志健  
  19.     NameList[14].py="luonan";//罗楠  
  20.     NameList[15].py="quegaoxiang";//阙高翔  
  21.     NameList[16].py="sugan";//苏淦  
  22.     NameList[17].py="suzhiqiang";//苏志强  
  23.     NameList[18].py="taojiayang";//陶嘉阳  
  24.     NameList[19].py="wujiawen";//吴嘉文  
  25.     NameList[20].py="xiaozhuomin";//肖卓明  
  26.     NameList[21].py="xujinfeng"//许金峰  
  27.     NameList[22].py="yanghaichun";//杨海春  
  28.     NameList[23].py="yeweixiong";//叶维雄  
  29.     NameList[24].py="zengwei";//曾玮  
  30.     NameList[25].py="zhengyongbin";//郑雍斌  
  31.     NameList[26].py="zhongminghua";//钟明华  
  32.     NameList[27].py="chenliyan";//陈利燕  
  33.     NameList[28].py="liuxiaohui";//刘晓慧  
  34.     NameList[29].py="panjinmei";//潘金梅  
  35.     for(i=0;i<NAME_NO;i++)  
  36.     {     
  37.         s0=0;  
  38.         f=NameList[i].py;  
  39.         for(r=0;*(f+r)!='\0';r++)/*将字符串的各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字*/  
  40.             s0=*(f+r)+s0;  
  41.         NameList[i].k=s0;  
  42.     }   
  43. }  

(2)  建立哈希表   

      用除留余数法构建哈希函数,用伪随机探测再散列法处理冲突

[cpp]  view plain  copy
  1. void CreateHashList()   
  2. {     
  3.     int i;  
  4.     for(i=0; i<HASH_LENGTH;i++)   
  5.     {    
  6.         HashList[i].py="";  
  7.         HashList[i].k=0;  
  8.         HashList[i].si=0;  
  9.     }  
  10.     for(i=0;i<HASH_LENGTH;i++)  
  11.     {     
  12.         int sum=0;  
  13.         int adr=(NameList[i].k)%M;//哈希函数  
  14.         int d=adr;  
  15.         if(HashList[adr].si==0)//如果不冲突  
  16.         {    
  17.             HashList[adr].k=NameList[i].k;  
  18.             HashList[adr].py=NameList[i].py;  
  19.             HashList[adr].si=1;  
  20.         }  
  21.         else//冲突    
  22.         {   
  23.             do  
  24.             {     
  25.                 d=(d+NameList[i].k%10+1)%M;//伪随机探测再散列法处理冲突      
  26.                 sum=sum+1;                 //查找次数加1      
  27.             }while (HashList[d].k!=0);  
  28.             HashList[d].k=NameList[i].k;  
  29.             HashList[d].py=NameList[i].py;  
  30.             HashList[d].si=sum+1;  
  31.         }  
  32.     }  
  33. }  

(3)  查找哈希表

      在哈希表中进行查找,输出查找的结果和关键字,并计算和输出查找成功的平均查找长度

[cpp]  view plain  copy
  1. void  FindList() //查找      
  2. {     
  3.     char name[20]={0};   
  4.     int s0=0,r,sum=1,adr,d;  
  5.     printf("请输入姓名的拼音:");       
  6.     scanf("%s",name);   
  7.     for(r=0;r<20;r++)   //求出姓名的拼音所对应的整数(关键字)  
  8.         s0+=name[r];   
  9.     adr=s0%M;   //使用哈希函数  
  10.     d=adr;  
  11.     if(HashList[adr].k==s0)          //分3种情况进行判断  
  12.         printf("\n姓名:%s   关键字:%d   查找长度为: 1",HashList[d].py,s0);   
  13.     else if (HashList[adr].k==0)   
  14.         printf("无此记录!");  
  15.     else  
  16.     {     
  17.         int g=0;  
  18.         do  
  19.         {     
  20.             d=(d+s0%10+1)%M;       //伪随机探测再散列法处理冲突                       
  21.             sum=sum+1;  
  22.             if(HashList[d].k==0)  
  23.             {    
  24.                 printf("无此记录! ");    
  25.                 g=1;       
  26.             }  
  27.             if(HashList[d].k==s0)  
  28.             {    
  29.                 printf("\n姓名:%s   关键字:%d   查找长度为:%d",HashList[d].py,s0,sum);   
  30.                 g=1;    
  31.             }  
  32.         }while(g==0);     
  33.     }    
  34. }  

(4) 显示哈希表

[cpp]  view plain  copy
  1. void Display()         
  2. {     
  3.     int i;  
  4.     float average=0;  
  5.     printf("\n地址\t关键字\t\t搜索长度\tH(key)\t 姓名\n"); //显示的格式  
  6.     for(i=0; i<50; i++)  
  7.     {     
  8.         printf("%d ",i);   
  9.         printf("\t%d ",HashList[i].k);  
  10.         printf("\t\t%d ",HashList[i].si);  
  11.         printf("\t\t%d ",HashList[i].k%30);  
  12.         printf("\t %s ",HashList[i].py);          
  13.         printf("\n");  
  14.     }  
  15.     for(i=0;i<HASH_LENGTH;i++)  
  16.         average+=HashList[i].si;   
  17.     average/=NAME_NO;  
  18.     pri  

(5) 主函数

[cpp]  view plain  copy
  1. void main()  
  2. {     
  3.     char ch1;  
  4.     InitNameList();                                  
  5.     CreateHashList ();   
  6.     do    
  7.     {     
  8.         printf("D. 显示哈希表\nF. 查找\nQ. 退出\n请选择: ");  
  9.         cin>>&ch1;  
  10.         switch(ch1)  
  11.         {  
  12.             case 'D':Display(); cout<<endl;break;  
  13.             case 'F':FindList();cout<<endl;break;  
  14.             case 'Q':exit(0);  
  15.         }  
  16.         cout<<"come on !(y/n):";  
  17.         cin>>&ch1;  
  18.     }while(ch1!='n');   
  19. }  

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值