构造散列函数

一、散列函数的选择有两条标准:简单和均匀。
     简单指散列函数的计算简单快速;
     均匀指对于关键字集合中的任一关键字,散列函数能以等概率将其映射到表空间的任何一个位置上。也就是说,散列函数能将子集K随机均匀地分布在表的地址集{0,1,…,m-1}上,以使冲突最小化。

二、常用散列函数
     为简单起见,假定关键字是定义在自然数集合上。
(1)平方取中法
     具体方法:先通过求关键字的平方值扩大相近数的差别,然后根据表长度取中间的几位数作为散列函数值。又因为一个乘积的中间几位数和乘数的每一位都相关,所以由此产生的散列地址较为均匀。
   【例】将一组关键字(0100,0110,1010,1001,0111)平方后得(0010000,0012100,1020100,1002001,0012321) 若取表长为1000,则可取中间的三位数作为散列地址集: (100,121,201,020,123)。
      相应的散列函数用C#实现很简单:
    public int Hash(int key)
    {
        
//假设key是4为整数
        key *= key;
        key 
/= 100;         //先求平方值,后去掉末尾的两位数
        return key % 1000;  //取中间三为数作为散列地址返回
    }

(2)除余法
     该方法是最为简单常用的一种方法。它是以表长m来除关键字,取其余数作为散列地址,即 h(key)=key%m
     该方法的关键是选取m。选取的m应使得散列函数值尽可能与关键字的各位相关。m最好为素数。
   【例】若选m是关键字的基数的幂次,则就等于是选择关键字的最后若干位数字作为地址,而与高位无关。于是高位不同而低位相同的关键字均互为同义词。
   【例】若关键字是十进制整数,其基为10,则当m=100时,159,259,359,…,等均互为同义词。
(3)相乘取整法
     该方法包括两个步骤:首先用关键字key乘上某个常数A(0<A<1),并抽取出key.A的小数部分;然后用m乘以该小数后取整。即:
          构造散列函数 - evilying2016 - 恶影 
     该方法最大的优点是选取m不再像除余法那样关键。比如,完全可选择它是2的整数次幂。虽然该方法对任何A的值都适用,但对某些值效果会更好。Knuth建议选取
              构造散列函数 - evilying2016 - 恶影 
     该函数的C#代码为:

     double  A  =   0.6180339887 ;
    
int  m  =   2 ;
    
public   int  Hash( int  key)
    {
        
double  d = key  * A;                 // 不妨设A和m已有定义
         return  ( int )(m  *  (d  -  ( int )d));  // (int)表示强制转换后面的表达式为整数
    }

4)折叠移位法
     根据哈希表长将关键字尽可能分成若干段,然后将这几段的值相加,并将最高位的进位舍去,所得结果即为其哈希地址。相加时有两种方法,一种是顺折,即把每一段中的各位值对其相加,称之为移位法;另一种是对折,像折纸条一样,把原来关键字中的数字按照划分的中界向中间段折叠,然后求和,称之位折叠法。
(5)随机数法
     选择一个随机函数,取关键字的随机函数值为它的散列地址,即h(key)=random(key) 其中random为伪随机函数,但要保证函数值是在0到m-1之间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值