查找--- 哈希表( 散列表)

哈希表优点:把数据的存储和查找消耗的时间大大降低,几乎可以看作是常数时间,而代价是消耗比较多的内存

散列表由两部分组成:桶数组,散列函数

1.桶数组

散列表的桶数组是一个大小为N的数组A,其中A的每个单元可看作一只“桶”,整数N表示数组的容量,如果关键字为整数,且

均匀地分散在范围[0,N-1]中,这个桶数组就是所需要的数组。关键字为K的元素e被简单地插入到桶A[k]中。

2.散列函数

散列函数将字典中的每个关键字k映射到区间[0,N-1]内的一个整数,其中N是这个散列表的桶数组的容量。这个方法的主要思想是利用散列函数值h(k)作为桶数组A的下标,而不是使用关键字k,即将数据项(k,e)存储在桶A[h(k)]中。  对于散列函数性能的评估有两个行为组成:一个是将关键字映射到一个整数上,称为散列编码;一个是将散列编码映射到桶数组下标内的一个整数上,称为压缩映射

    关键字——>散列编码——>压缩映射到桶数组区间

3.压缩映射

1)除法散列法

       h(k)=|k| mod N;

   如果N为素数,则该方法有助于"扩散"散列值的分布;如果N不是素数,关键字分布中的模式在散列编码分布中出现重复的可能性更大,因而会有冲突。

2)MAD方法(乘加与除方法)

   h(k)=|ak+b| mod N;其中N是素数,a,b是在确定压缩函数时随机选取的非负整数,满足a mod N 不等于0.

 

3)余数法:先估计整个哈希表中的表项目数目大小。然后用这个估计值作为除数去除每个原始值,得到商和余数。用余数作为哈希值。因为这种方法产生冲突的可能性相当大,因此任何搜索算法都应该能够判断冲突是否发生并提出取代算法。 

4)折叠法:这种方法是针对原始值为数字时使用,将原始值分为若干部分,然后将各部分叠加,得到的最后四个数字(或者取其他位数的数字都可以)来作为哈希值。 

5)基数转换法:当原始值是数字时,可以将原始值的数制基数转为一个不同的数字。例如,可以将十进制的原始值转为十六进制的哈希值。为了使哈希值的长度相同,可以省略高位数字。 

6)数据重排法:这种方法只是简单的将原始值中的数据打乱排序。比如可以将第三位到第六位的数字逆序排列,然后利用重排后的数字作为哈希值。

4.冲突处理模式

装填因子:一个良好的散列函数将字典中的n个数据存储在容量为N的桶数组中,并期望每个桶的大小为n/N,则为散列表的装填因子。数据个数与桶数组容量的比,通常装填因子小于1.

1)开放定址法

      当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的地址则表明表中无待查的关键字,即查找失败。

注意:

①用开放定址法建立散列表时,建表前须将表中所有单元(更严格地说,是指单元中存储的关键字)置空。

②空单元的表示与具体的应用相关

    Hi=(H(key)+di) MOD m, i=1,2,3,……k(k<=m-1);

  H(key)为哈希函数;m为哈希表的长度;di为增量序列;增量序列有3种取法:

第一种:线性探测再散列       di=1,2,3,4……m-1;

       使用线性探测散列会产生聚焦或堆积(散列地址不同的结点争夺同一个后继散列地址的现像叫聚焦或堆积)为了减少堆积的发生,不能像线性探查法那样探查一

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值