美文网首页数据结构与算法
MIT算法导论七 哈希表

MIT算法导论七 哈希表

作者: Alex90 | 来源:发表于2018-01-03 15:32 被阅读0次

    - 哈希表
    - 哈希函数选择
    - 哈希碰撞

    由“符号表问题”引入什么是哈希
    有一个表S有n条记录,每个记录(通常认为是指向数据的指针x)有一个Key和一些数据(属于键值key的附加数据),我们需要对这个表进行一系列操作:Insert、Search、Delete

    最简单实现:直接映射表(键值分布比较小时有用)
    假设键值来自一个有m个元素的集合U,并假设键值互相独立,建立一个数组T[0,1…m-1],对于关键字k,如果在集合U中,把它存储在T[k]的位置上,查询、插入、删除的时间都是O(1)

    这个方法的缺陷
    如果关键字的范围比较大,那么建立的这个表的长度那么就大到无法接受
    如果关键字不连续非常浪费空间


    Hashing
    实现字典的一种数据结构就是哈希表,又称散列表,根据一个哈希函数将集合S中的关键字映射到一个表中,这个表就称为哈希表,就是把上述的直接映射,变成一个函数映射,这个函数就是哈希函数,而这种方法就称为Hashing

    映射过程会遇到的问题:碰撞
    多个键值经过哈希后指向同一个槽,碰撞有多种解决办法

    链接法
    把相同键值的数据存储在链表中
    最坏情况,所有的键都落到一个槽中,操作的复杂度等于在链表中操作复杂度θ(n)
    最好情况,O(1)

    给定一个能存放n个元素,具有m个槽的散列表T,定义T的装载因子α为n/m,假设计算key的时间为O(1),查找关键字为k的元素的时间取决于T[h(k)]的链表长度,平均情况下一次成功的查找需要θ(1+α)的时间


    如何选择哈希函数h
    一个好的哈希函数应该能够将关键字均匀的分配到哈希表T中
    关键字的分布率不应该影响这种均匀性

    最常用的哈希函数

    除法散列法
    定义hash函数为 h(k) = k mod m
    m的原则就是m选为质数且不能太接近2或者10的幂次
    因为键值的低位可能具有某种分布规律,如果选择2或者10的幂次容易出现冲突

    极端的一些例子
    m=2
    表中的所有的奇数位置都没用到,这便是关键字的分布规律(全偶)影响到了映射的均匀性
    m=2r
    我们把关键字用二进制表示,那么如下的一个关键字,

    只与后6位有关

    乘法散列法
    设m=2r, 计算机是w-bit长的字,定义哈希函数是h(k) = (A*k mod 2^w) rsh (w-r)
    rsh->右移位,A是一个在(2^w-1, 2^w)范围内的奇数

    分析这个哈希函数(A*k mod 2^w)这一部分就是将乘法得到的结果只取一个字长 ,然后再rsh w-r位,就刚好只保留了最大是m的结果,可以很好的映射到表中。


    假设m=23,字长w是7-bit ,用车轮法考虑那个乘法过程:

    车轮法

    其他解决碰撞的方法

    开放寻址法
    解决思路:当遇到冲突时那么便去寻找下一个空的地址,只要表足够大(表长度要大于集合S的数量),空的地址总能找到

    线性探查
    H(k, i) = (H(k) + i) mod m (i = 1,2,3,4....)

    假设m=13,i=1,H(18) = 5 发生冲突,寻找下一个地址
    H(18) = (5 + 1) mod 13 = 6 继续发生冲突,寻找下一个地址
    ...
    这种算法可能遇到一次集群(二次集群,取决与每次加的i,问题是相同的)的问题,如果某个连续空间都被占用,浪费效率
    

    二次哈希
    H(k, i) = (H_1(k) + i·H_2(k)) mod m (i = 1,2,3,4)

    对于一个开放寻址的哈希表,α=n/m<1,那么一次不成功搜索的预期探寻次数为1/(1-α).


    证明过程

    相关文章

      网友评论

        本文标题:MIT算法导论七 哈希表

        本文链接:https://www.haomeiwen.com/subject/vvbmgxtx.html