散列表-2

处理冲突的方法
任何设计出来的散列函数都不可能绝对地避免冲突,为此,必须考虑在发生冲突时应该如何进行处理,即为产生冲突的关键字寻找下一个“空”的Hash地址。
假设已经选定散列函数H(key),下面用Hi表示发生冲突后第i次探测的散列地址。
一.开放定址法
所谓开放定址法,指的是可存放新表项的空闲地址既指向它的同义词表项开放,又向它的非同义词表项开放。其数学递推公式Hi=(H(key)+di)%m,其中,i=1,2,…,k(k<=m-1);m表示散列表表长;di为增量序列。
当增量序列即di确定后,则对应的处理方法是确定的。通常有以下四种取法:
1)线性探测法
当di=1,2,…,m-1,称为线性探测法。这种方法的特点是:冲突发生时,顺序查看表中的下一个单元(当探测到表尾地址m-1时,下一个探测地址是表首地址0),直到找出下一个空闲单元(当表未填满时一定能找到一个空闲单元)或查遍全表。
2)平方探测法
当di=1²,-1²,2²,-2²,…,k²,-k²,其中k≤m/2,m必须是一个可以表示成4k+3的质数,又称二次探测法。
平方探测法是一种较好的处理冲突的方法,可以避免出现“堆积”问题,它的缺点是不能探测到散列表上的所有单元,但至少能探测到一般单元。
3)再散列法
当di=Hash2(Key),又称为双散列法。需要使用两个散列函数,当通过第一个散列函数H(Key)得到的地址发生冲突时,则利用第二个散列函数Hash2(Key)计算该关键字的地址增量。再散列法中,最多经过m-1次探测会遍历表中所有位置,回到H0位置。
4)伪随机序列法
当di=伪随机数序列,称为伪随机序列法。

注意:在开放地址的情形下,不能随便物理删除表中已有元素,因为若删除元素将会截断其他具有相同散列地址的元素的查找地址。所以,若想删除一个元素时,给它做一个删除标记,进行逻辑删除。但这样做的副作用是:在执行多次删除后,表面看上去散列表是满的,实际上有许多位置没有利用,因此需要定期维护散列表,要把删除标记的元素物理删除。

二.拉链法
对于不同的关键字可能会通过散列函数映射到同一地址,为了避免同义词发生冲突,可以把所有的同义词存储在一个线性链表中,这个线性链表由其散列地址唯一标识。假设散列地址为i的同义词链表的头指针存放在散列表中的第i个单元中,因而查找,插入,删除操作主要在同义词链中进行。拉链法适合于经常进行插入删除操作的情况。


散列表查找及性能分析
散列表的查找过程与构造散列表的过程基本一致。对于一个给定的关键字key,根据散列函数可以计算出其散列地址,执行步骤如下:
初始化:Addr=Hash(key);
①检测查找表中地址为Addr的位置上是否有记录,若没有记录,返回查找失败;若有记录,比较它与key值,若相等,返回查找成功标志,否则执行下一步。
②用给定的处理冲突方法计算“下一个散列地址”,并把Addr置wei此地址,转入步骤①

散列表的查找效率取决与三个因素:散列函数,处理冲突的方法和装填因子

装填因子:散列表的装填因子一般记为α,定义为一个表的装满程度,即α=表中记录数n/散列表长度m
散列表的平均查找长度依赖于散列表的装填因子α,而不直接依赖于n或m。直观上看,α越大,装填程度越满,发生冲突的可能性就越大,反之发生冲突的可能性越小。


虽然散列表在关键字与记录的存储位置之间建立了直接映像,但由于冲突的发生,使得散列表的查找过程仍然是一个给定值和关键字进行比较的过程。因此,仍需以平均查找长度作为衡量散列表的查找效率的度量。
更多详细内容,查看我的个人博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值