zoukankan      html  css  js  c++  java
  • 散列表 (Hash table,也叫哈希表)

         散列表是根据关键字(Key value)而直接访问在内存存储位置的数据结构。也就是说,它通过把键值通过一个函数的计算,映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

       散列表是普通数组概念的推广,它支持insert,search,delete操作。在实践中,它的效率还是很高的,在一些合理的假设下,在散列表中查找一个元素的期望时间为O(1).

    1直接寻址表

    如下图,在关键字全域U,比较小时,直接寻址是一种简单而有效的技术。

    image

    其实操作类似于数组了,只不过索引是key(关键字)。这时的操作比较简单如下:

    image

    2散列表(哈希表)

    直接寻址有个明显的问题,如果域U很大,在计算机内存有限的限制下,实现它就不实际了。因为K相对于U很小,分配给T的空间大部分都浪费了。

    所以在哈希表中,我们加入 散列函数,就是把从实际关键字k,映射到散列表[0…M-1]的槽位上。这样空间开销就从|U|缩减到了M.

    但是这样会带来问题,就是碰撞(collision),因为是多对少的映射,碰撞不可避免。

    image

    解决碰撞的方法之一是链接法(chaining):把散列到同一槽中的所有元素都放在一个链表中。如下图:

    image

     

     

    3散列表的性能分析

        若给定一个能存放n个元素的,具有m个槽位的散列表T.若用链接法,最坏的情况效果会很差,所有元素都被映射到一个槽里面。所以我们要求映射函数h,要将所有的关键字均匀分布在m个槽位上。

        假设,任何元素散列到m个槽中的每个槽是等可能性,且相互独立的。称这个假设为简单一致散列(simple uniform hashing).

        在上面的假设下,且n=O(m).在散列表中所有操作的期望时间为O(1).

    4散列函数的选择

    好的散列函数应尽可能满足,简单一致散列的假设。

    4.1除法散列法

    通过取k除以m的余数,将关键字映射到m个槽中去,即

    h(k)=k mod m

    m不应该是是2的整数次幂。若m=2^p,则h(k)就是k的p个最低位数字,我们不清楚关键字的p最低位是否均匀,所以m应该尽量选择不太接近2的整数幂的质数。

     

    4.2乘法散列法

    用关键字k乘以常数A,并且抽出kA的小数部分,然后用m乘以这个值,再取底floor.即:

    h(k)=floor( m( k*A mod 1) )

    乘法散列,m没有太多限制,一般取2的整数次幂,A一般取,(sqrt(5)-1)/2.

    4.3全域散列(universal hashing):

    随机的选择散列函数,使之独立于要存储的关键字,这种方法称为全域散列。这样无论关键字怎么选,其平均性能都很好(思想类似于随机快速排序,为了避免最坏的情况,让最后一个数字与前面的随机交换)。

    5开放寻址法(open addressing)

    未完待续

  • 相关阅读:
    ruby计算平方和开方
    Silverlight中DataGrid翻页或者滚动时CheckBox/RadioButton显示的问题
    bat文件设置ip地址
    gcc编译多线程
    TCP Nagle算法
    fork父子进程 信号处理
    Unix守护进程的创建示例
    inline内联函数
    volatile类型
    ioctl获取接口名称、IP地址、MAC地址、广播地址等
  • 原文地址:https://www.cnblogs.com/Dzhouqi/p/3394364.html
Copyright © 2011-2022 走看看