哈希表的问题总结

来源:互联网 发布:mac终端bash 编辑:程序博客网 时间:2024/06/06 05:01

一、哈希表

哈希表,也称散列表,英文名称Hash Table。是根据关键码值(Key value)而直接进行访问的数据结构,也就是说通过把关键码值映射到表中一个位置来访问记录以便加快查找的速度。这个映射的函数叫做散列函数,存放记录的数组叫做散列表

可以定义为:给定表Table,存在函数F(key),对任意给定的关键字key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表Table为哈希(Hash)表,函数F(key)为哈希(Hash)函数。

二、哈希函数

即哈希函数,也称散列函数,意义:根据关键码值key计算出对应记录的存储位置,position = F(key)。

散列函数满足以下条件:

(1)对输入值运算,得到一个固定长度的摘要(Hash value);

(2)不同的输入值可能产生相同的输出值;

比如:F(x) = x mod 12F(x) = (x | 0×0000FFFF) XOR (x >> 16)等就可以认为是一个散列函数。同时我们还希望散列函数能满足以下几点:

(1)散列的输出值尽量接近均匀分布;

(2)自变量X的微波变化可以使F(x)发生非常大的变化,即“雪崩效应”;

三、构造Hash函数的方法

(1)直接定址法:哈希函数为关键字的线性函数,H(key) = key 或者 H(key) = a * key + b

          此法适于地址集合的大小 == 关键字集合的大小,其中a和b为常数。

(2)数字分析法:假设关键字集合中的每个关键字都是由 s 位数字组成 (u1, u2, …, us),分析关键字集中的全体,并从中提取分布均匀的若干位或它们的组合作为地址

           此法适于能预先估计出全体关键字的每一位上各种数字出现的频度

(3)平方取中法: 以关键字的平方值的中间几位作为存储地址。求“关键字的平方值” 的目的是“扩大差别” ,同时平方值的中间各位又能受到整个关键字中各位的影响

           此法适于关键字中的每一位都有某些数字重复出现频度很高的现象

(4)折叠法:将关键字分割成若干部分,然后取它们的叠加和为哈希地址。两种叠加处理的方法:移位叠加:将分割后的几部分低位对齐相加;间界叠加:从一端沿分割界来回折叠,然后对齐相加

          此法适于关键字的数字位数特别多

(5)除留余数法:设定哈希函数为:H(key) = key MOD p   ( p≤m ),其中, m为表长,p 为不大于 m 的素数,或 是不含 20 以下的质因子

(6)随机数法:设定哈希函数为:H(key) = Random(key)其中,Random 为伪随机函数

          此法适于对长度不等的关键字构造哈希函数

实际造表时,不论采用哪种哈希函数构建哈希表,总的原则是使产生冲突的可能性尽可能地小

四、哈希表的冲突处理

由上面的方法可以看到,不论哪种方面总会产生冲突,处理冲突的实际含义是为冲突的关键字寻找下一个哈希地址。

1、开放地址法

这个方法的基本思想是:当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。这个过程可用下式描述: H i ( key ) = ( H ( key )+ d i ) mod m ( i = 1,2,…… , k ( k ≤ m – 1)) ,其中: H ( key ) 为关键字 key 的直接哈希地址, m 为哈希表的长度, di 为每次再探测时的地址增量。 
采用这种方法时,首先计算出元素的直接哈希地址 H ( key ) ,如果该存储单元已被其他元素占用,则继续查看地址为 H ( key ) + d 2 的存储单元,如此重复直至找到某个存储单元为空时,将关键字为 key 的数据元素存放到该单元。 
增量 d 可以有不同的取法,并根据其取法有不同的称呼: 

(1) d i = 1 , 2 , 3 , ……线性探测再散列; 

(2) d i = 1^2 ,- 1^2 , 2^2 ,- 2^2 , k^2, -k^2……二次探测再散列; 

(3) d i = 伪随机序列 伪随机再散列,随机探测的基本思想是:将线性探测的步长从常数改为随机数,即令: j = (j + RN) % m ,其中 RN 是一个随机数。在实际程序中应预先用随机数发生器产生一个随机序列,将此序列作为依次探测的步长。这样就能使不同的关键字具有不同的探测次序,从而可以避 免或减少堆聚。基于与线性探测法相同的理由,在线性补偿探测法和随机探测法中,删除一个记录后也要打上删除标记。;

:设有哈希函数 H ( key ) = key mod 7 ,哈希表的地址空间为 0 ~ 6 ,对关键字序列(32 , 13, 49 , 55, 22 , 38, 21 )按线性探测再散列和二次探测再散列的方法分别构造哈希表。 
解:( 1 )线性探测再散列:

32 % 7 = 4 ; 

13 % 7 = 6 ; 

49 % 7 = 0 ; 

55 % 7 = 6 发生冲突,下一个存储地址(6 + 1) % 7 = 0 ,仍然发生冲突,再下一个存储地址:(6 + 2) % 7 = 1 未发生冲突,可以存入; 

22 % 7 = 1 发生冲突,下一个存储地址是:( 1 + 1 )% 7 = 2 未发生冲突; 

38 % 7 = 3 ; 

21 % 7 = 0 发生冲突,按照上面方法继续探测直至空间 5 ,不发生冲突,所得到的哈希表对应存储位置: 

下标: 0 1 2 3 4 5 6 49 55 22 38 32 21 13 

( 2 )二次探测再散列: 

下标: 0 1 2 3 4 5 6 49 22 21 38 32 55 13 

注意:对于利用开放地址法处理冲突所产生的哈希表中删除一个元素时需要谨慎,不能直接地删除,因为这样将会截断其他具有相同哈希地址的元素的查找地址,所以,通常采用设定一个特殊的标志以示该元素已被删除。

2、拉链法

拉链法解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于 1,但一般均取α≤1。

3、再哈希法

这种方法的思想是同时构造多个不同的哈希函数:H1=RH1(key) i=1,2,3...,k。当哈希地址Hi=RH1(key)发生冲突时再计算Hi=RH2(key)...,直到冲突不再产生。这种方法不易产生聚焦,但增加了计算时间。


2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东金条银行卡被冻结还不了怎么办 在瑞士刚买的浪琴手表不走了怎么办 刚买的手表表镜有划痕 怎么办 唯品会上买的手表有质量问题怎么办 我买的对方材料没开票给我怎么办 给对方修完车车主不给发票怎么办 买苹果手机花呗额度不够怎么办 苹果手机用别人的手机卡激活怎么办 小米商城花呗分期额度不够怎么办 淘宝已经形成订单商家不发货怎么办 小米商城退款后又想买了怎么办 淘宝退货退款后不想退了怎么办 在转转的商品被屏了怎么办 不懂如何挑选适合自己的衣服怎么办 淘宝购买商品给顾客造成损失怎么办 微信购物地址写错了怎么办 微信购物后一直不发货怎么办 微信购物不发货也不退款怎么办 淘宝退货不小心点了确认收货怎么办 外卖不小心点了确认收货怎么办 圆通快递单号查不到物流信息怎么办 在京东买东西没收到退回去了怎么办 我的东西没收到退回去了怎么办 快递丢了快件丢失了快递公司怎么办 在天猫超市买东西订单关闭了怎么办 淘宝上退货店家收到货不理怎么办 淘宝申请退货退款卖家拒绝怎么办 闲鱼退货卖家拒绝退款怎么办 淘宝退货店家收到货不退款怎么办 卖家拒绝申请我退货了怎么办 衣服洗了卖家拒绝退货怎么办 在京东买的小米手机屏摔碎了怎么办 取消流量漫游后省内不限量怎么办 在淘宝买东西不发货也不退款怎么办 微信上充值电话号码空号怎么办 支付宝转帐到已停机的号码上怎么办 支付宝充话费充错号码怎么办 支付宝话费充错号码了怎么办 村书记打了人不给赔偿药费怎么办 淘宝退给的支付的钱怎么办 淘宝支付了钱没回信息怎么办