哈希(hash)算法的学习(一)

首先要解释一下键的概念,如果学过数据库的话这段可以跳过,比如现在有个Record类记录我们每个人的基本信息,类成员有姓名,学历,身高,身份证号,出生年月等,那么这些成员中哪一个可以作为唯一标识去区别呢,很明显身份证号是可以的,那么我们就可以认为身份证号码可以作为Record类的一个键

一 :算法摘要

1,初始化操作 ---- 首先必须申明一个数组去容纳哈希表,接下来必须对数组中的所有元素初始化以表明他们为空,这个过程的完成依赖于应用,它的实现经常是在Record的成员中设置一个独立的变量来指示。

2,插入操作 ---- 首先要计算它的键的哈希函数。如果对应位置为空则可以插入,如果对应位置的键是相等的,则不允许插入;如果这个位置上有不同键的记录,则有必要解决冲突。

3,检索操作 ---- 此操作与插入操作类似。首先计算这个键的哈希函数,如果期望的记录就在该位置中,检索成功;当此位置不空且没有检索完所有位置,则需要遵循解决冲突的同样步骤;如果发现空位或者已检索完所有位置,检索失败

二:选择哈希函数

1,选取准则:

1)它应是简单的且易于计算的

2)它应实现在下标范围内真正出现的键的平均分布

2,三种方法:

1)截取 ---- 忽略键的一部分,并用剩余部分直接作为下标。例如,如果键是8位的,二哈希表有1000个位置,则从右边取第一位,第二位,和第五位数字作为哈希函数,这样21 296 876就映射到976,截取是非常快的方法,但它经常不能在表中均匀分布这些键。

2)折叠 ---- 将键划分成几部分并用一种方便的形式(经常使用加法或乘法)将这几部分组合起来以得到下标。例如8位的数字分为3 3 2的组合,再讲这3个组合加起来,如果有必要的话还可以在适当的下表范围内截取这个和。那么21 296 876映射到 212+968+76=1256,截取后得到256.由于键中所有信息都能够影响函数的值,因此它能比截取法获得更好的下标分布。

3)模运算  ---- 将键转换为整数,在使用C++中的%运算。模的最佳选择经常是一个质数,质数通常能很均匀的分布键。因此在选择哈希表的长度时通常不选择1000,较好的方法是选择997或者1009.取余通常是推断哈希函数的最佳方式。

三:开放定址的冲突解决方案

1,线性探测 ---- 从发生冲突的位置开始,在表中顺序的查找期望的键或空位置。这个表格将被看做环形的,这样到达最后一个位置时,可以在表格的第一个位置继续查找;这种方法的缺点是当当表格大约半满时,存在聚集的倾向,顺序查找需要的时间越来越长

2,二次探测 ---- 如果哈希地址h存在冲突,二次探测将探测表格中的位置h+1,h+4,h+9。。。,即探测位子h+i^2(换言之,此处的增量函数是i^2)。这种方法有两个要注意的:1)探测位置最多为(hash_size+1)/2,如果超过则认为表已满。2)二次探测可以不用乘法实现:在对位置h第一次探测后,将增量设为1,在每次相继探测时,在增量已被加到前一位值上以后将增量加2,注意到 h+1+3+5+。。。+(2i-1)= h+i^2(数学归纳法)

先写到这里 代码部分 下次再贴出来,不知道为啥不能显示缩进,看起来有些累

代码链接http://blog.csdn.net/mjlsuccess/article/details/14003961


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值