zoukankan      html  css  js  c++  java
  • 哈希表——线性探測法、链地址法、查找成功、查找不成功的平均长度

    一、哈希表

    1、概念

           哈希表(Hash Table)也叫散列表,是依据关键码值(Key Value)而直接进行訪问的数据结构。它通过把关键码值映射到哈希表中的一个位置来訪问记录,以加快查找的速度。

    这个映射函数就做散列函数。存放记录的数组叫做散列表。

    2、散列存储的基本思路

           以数据中每一个元素的keywordK为自变量。通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值相应的单元中。

    3、哈希表查找的时间复杂度

           哈希表存储的是键值对,其查找的时间复杂度与元素数量多少无关。哈希表在查找元素时是通过计算哈希码值来定位元素的位置从而直接訪问元素的,因此,哈希表查找的时间复杂度为O(1)。


    二、经常使用的哈希函数

    1.   直接寻址法

    取keyword或者keyword的某个线性函数值作为哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b为整数),这样的散列函数也叫做自身函数.假设H(Key)的哈希地址上已经有值了,那么就往下一个位置找,知道找到H(Key)的位置没有值了就把元素放进去.

    2.   数字分析法

    分析一组数据,比方一组员工的出生年月,这时我们发现出生年月的前几位数字一般都同样,因此,出现冲突的概率就会非常大,可是我们发现年月日的后几位表示月份和详细日期的数字区别非常大,假设利用后面的几位数字来构造散列地址,则冲突的几率则会明显减少.因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址.

    3.   平方取中法

    取keyword平方后的中间几位作为散列地址.一个数的平方值的中间几位和数的每一位都有关。

    因此,有平方取中法得到的哈希地址同keyword的每一位都有关。是的哈希地址具有较好的分散性。

    该方法适用于keyword中的每一位取值都不够分散或者较分散的位数小于哈希地址所须要的位数的情况。

    4.   折叠法

    折叠法即将keyword切割成位数同样的几部分,最后一部分位数能够不同,然后取这几部分的叠加和(注意:叠加和时去除进位)作为散列地址.数位叠加能够有移位叠加和间界叠加两种方法.移位叠加是将切割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向还有一端沿切割界来回折叠,然后对齐相加.

    5.   随机数法

    选择一个随机数,去keyword的随机值作为散列地址,通经常使用于keyword长度不同的场合.

    6.   除留余数法

    取keyword被某个不大于散列表表长m的数p除后所得的余数为散列地址.即H(Key)=Key MOD p,p<=m.不仅能够对keyword直接取模,也可在折叠、平方取中等运算之后取模。对p的选择非常重要,一般取素数或m,若p选得不好。则非常easy产生冲突。

    一般p取值为表的长度tableSize。


    三、哈希冲突的处理方法

    1、开放定址法——线性探測

    线性探測法的地址增量di = 1, 2, ... , m-1,当中,i为探測次数。该方法一次探測下一个地址。知道有空的地址后插入。若整个空间都找不到空余的地址,则产生溢出。

    线性探測easy产生“聚集”现象。当表中的第i、i+1、i+2的位置上已经存储某些keyword,则下一次哈希地址为i、i+1、i+2、i+3的keyword都将企图填入到i+3的位置上,这样的多个哈希地址不同的keyword争夺同一个后继哈希地址的现象称为“聚集”。聚集对查找效率有非常大影响。

    2、开放地址法——二次探測

    二次探測法的地址增量序列为 di = 12, -12, 22。 -22,… 。 q2, -q(q <= m/2)。二次探測能有效避免“聚集”现象,可是不可以探測到哈希表上全部的存储单元,可是至少可以探測到一半。

    3、链地址法

    链地址法也成为拉链法。

    其基本思路是:将全部具有同样哈希地址的而不同keyword的数据元素连接到同一个单链表中。假设选定的哈希表长度为m,则可将哈希表定义为一个有m个头指针组成的指针数组T[0..m-1]。凡是哈希地址为i的数据元素,均以节点的形式插入到T[i]为头指针的单链表中。而且新的元素插入到链表的前端,这不仅由于方便。还由于常常发生这种事实:新近插入的元素最优可能不久又被訪问。

    链地址法特点

    (1)拉链法处理冲突简单。且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短; 
    (2)因为拉链法中各链表上的结点空间是动态申请的。故它更适合于造表前无法确定表长的情况。 
    (3)开放定址法为降低冲突。要求装填因子α较小。故当结点规模较大时会浪费非常多空间。而拉链法中可取α≥1,且结点较大时,拉链法中添加的指针域可忽略不计,因此节省空间; 
    (4)在用拉链法构造的散列表中,删除结点的操作易于实现。仅仅要简单地删去链表上对应的结点就可以。而对开放地址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是由于各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。

    因此在用开放地址法处理冲突的散列表上运行删除操作。仅仅能在被删结点上做删除标记,而不能真正删除结点。

    四、哈希表的装填因子

    装填因子 = (哈希表中的记录数) /  (哈希表的长度)

    装填因子是哈希表装满程度的标记因子。值越大。填入表中的数据元素越多,产生冲突的可能性越大。


    五、不同处理冲突的平均查找长度

     

    例:

    如果散列表的长度是13,三列函数为H(K) = k % 13,给定的keyword序列为{32。 14, 23, 01。 42, 20。 45, 27, 55。 24。 10。 53}。分别画出用线性探測法和拉链法解决冲突时构造的哈希表,并求出在等概率情况下,这两种方法的查找成功和查找不成功的平均查找长度。

    (1)线性探測法:

    查找成功时的查找次数等于插入元素时的比較次数,查找成功的平均查找长度为:

    ASL = (1+2+1+4+3+1+1+3+9+1+1+3)/12 = 2.5

    查找成功时的查找次数:第n个位置不成功时的比較次数为,第n个位置到第1个没有数据位置的距离:如第0个位置取值为1,第1个位置取值为2.

    查找不成功的平均查找次数为:

    ASL = (1+2+3+4+5+6+7+8+9+10+11+12)/ 13 = 91/13

    (2)链地址法

    查找成功时的平均查找长度:

    ASL = (1*6+2*4+3*1+4*1)/12 = 7/4

    查找不成功时的平均查找长度:

    ASL = (4+2+2+1+2+1)/13

    注意:查找成功时。分母为哈希表元素个数,查找不成功时,分母为哈希表长度。

  • 相关阅读:
    Windows Phone 7 电话本相关的操作
    Windows CE 下判断 URL 地址是否有效
    cigarettes
    开灯问题
    日期计算
    小学生算术
    另一种阶乘问题
    鸡兔同笼
    笨小熊
    6174问题
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7307596.html
Copyright © 2011-2022 走看看