zoukankan      html  css  js  c++  java
  • 哈希表

    哈希表

    使用哈希函数确定下标以插入数据的数组叫哈希表

    哈希化

    通过哈希函数把一个数字从大的范围转化为小范围的数字叫哈希化

    把关键字转化为数组下标

    1、关键字不需要转换,比如员工编号从0到1000,关键字员工编号可以直接做为数组下标

    2、关键字需要转换,把一部英文字典装入哈希表,a是1,b是2,c是3,依此类推,z是26,还有空格是0

    1)数字相加 cats=3+1+20+19=43
    假设单词最长有10个字母组成a的编码是1,zzzzzzzzzz是26*10=260,这样单词编码的范围是从1到260。不幸的是,字典中一共有50000个单词。数组下标太少,每个数组元素大概要存储50000/260=192个单词。

    2)幂的连乘
    7564= 7*10+ 5*10+ 6*101  +  4*100
    cats=  3*27+ 1*10+ 20*101+ 19*100
    这样每个单词对应独一无二的一个数字
    最长的10个字母的单词zzzzzzzzzz,将转化成26*279+26*278+26*277+26*276+26*275+26*274+26*273+26*272+26*271+26*270
    仅279就超过7000000000000,结果非常巨大,内存中的数组根本不可能有这么多的单元,产生的数组下标太多

    3)哈希函数

    取余法:index = x / arrayLength

    哈希化后的冲突

    1、开放地址法

    期望的数组平均起来,每两个数组单元,有一个单词;有些单元没有单词,而有些单元有多个单词。所以设计数组大小应该两倍于需要存储的数据量,这样可能一半的单元是空的,冲突后,找到数组的一个空位并填入。

    1)线性探测:+1,+2,+3,+4

    装填因子是二分之一或三分之二时,哈希表的性能最好;装填因子接近1时,哈希表效率非常低。一连串已填充的单元越来越长,叫聚集,大块的聚集降低了哈希表的效率。

    2)二次探测:+1,+4,+9,+16

    3)再哈希法

    二次探测的问题,产生的步长总是固定的1、4、9、16...,再哈希法不同的关键字使用不同的步长
    再哈希法函数必须具备的特点:1、和第一个哈希函数不同。2、不能得到0,否则总是原地踏步
    一个再哈希函数:stepSize = constant - ( key % constant ),constant是质数且小于数组容量
    装填因子是9/10或更大,大多数数据项还是能一次哈希函数找到

    再哈希法和二次探测要求数组容量是一个质数,否则会造成死循环

    2、链地址法

    当装填因子是1时,大约三分之一的单元是空白单元,三分之一的单元有一个数据项,三分之一的单元有两个或更多的数据项。

    链地址法装填因子可以达到1以上,对性能影响并不大;找到初始单元需要O(1)的时间级,搜索链表的时间与链表的平均数据项成正比。

    表容量不像在再哈希法和二次探测中显得那么重要,链地址法不需要探测,不会出现死循环;但当表容量不是质数时,还是能够导致聚集

    哈希表优缺点

    优点:
    哈希表的速度明显比树快。插入、查找、删除时间复杂度接近O(1)。

    缺点:
    基于数组,难于扩展。哈希函数根据数组大小计算数据项的位置,所以在扩展哈希表时,不能简单地从一个数组向另一个数组拷贝数据;需要顺序遍历旧数组,重新计算数据项的下标,再插入新数组
    不能以任何一种顺序遍历数据
    某些哈希表被基本填满时,性能下降得非常严重

  • 相关阅读:
    Period 计算日期之间的时间差遇到的问题
    Spring cloud jenkins 使用问题笔记jenkins publish over ssh (Exec exit status not zero. Status)
    Linux中scp命令获取远程文件的方法
    HTML5+CSS3从入门到精通 pdf下载
    Oracle RMAN-08137报错处理
    SQL中如何使用EXISTS替代IN
    你撸代码时,会戴耳机吗?
    MySQL必知必会 pdf下载
    SqlServer的sa账号被锁定
    windows系统如何查看端口被占用、杀进程
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10424364.html
Copyright © 2011-2022 走看看