zoukankan      html  css  js  c++  java
  • open live writer 测试

    什么是Hash表

    1.定义

    Hash(散列/哈希),就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出(引出后面碰撞处理)而不可能从散列值来唯一的确定输入值。

    数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法,我们可以理解为“链表的数组”,如图:

                                                       clip_image001

    这样的设计的数据结构需要考虑的最重要的问题就是,如何将数据存入?

    2.散列法

    元素特征转变为数组下标的方法就是散列法。散列法当然不止一种,下面列出三种比较常用的:

    (1)除法散列法

    最直观的一种,上图使用的就是这种散列法,公式:

    index = value % 16

    学过汇编的都知道,求模数其实是通过一个除法运算得到的,所以叫“除法散列法”。

    (2)平方散列法

    求index是非常频繁的操作,而乘法的运算要比除法来得省时(对现在的CPU来说,估计我们感觉不出来),所以我们考虑把除法换成乘法和一个位移操作。公式:

    index = (value * value) >> 28 (右移,除以2^28。记法:左移变大,是乘。右移变小,是除。)

    如果数值分配比较均匀的话这种方法能得到不错的结果,但我上面画的那个图的各个元素的值算出来的index都是0——非常失败。也许你还有个问题,value如果很大,value * value不会溢出吗?答案是会的,但我们这个乘法不关心溢出,因为我们根本不是为了获取相乘结果,而是为了获取index。

    (3)斐波那契(Fibonacci)散列法

    平方散列法的缺点是显而易见的,所以我们能不能找出一个理想的乘数,而不是拿value本身当作乘数呢?答案是肯定的。

    1. 对于16位整数而言,这个乘数是40503

    2. 对于32位整数而言,这个乘数是2654435769

    3. 对于64位整数而言,这个乘数是11400714819323198485

    这几个“理想乘数”是如何得出来的呢?这跟一个法则有关,叫黄金分割法则,而描述黄金分割法则的最经典表达式无疑就是著名的斐波那契数列,即如此形式的序列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,…。另外,斐波那契数列的值和太阳系八大行星的轨道半径的比例出奇吻合。

    对我们常见的32位整数而言,公式:

    index = (value * 2654435769) >> 28

    如果用这种斐波那契散列法的话,那上面的图就变成这样了:

                                              clip_image002

    3.基本原理及要点

    hash函数 : 原始数据 ---(某些操作)----> 重复性小的int值 ----(散列函数)---->数组下标

    碰撞处理(hash函数计算出的下标相同的情况)

    一种是open hashing,也称为拉链法;另一种就是closed hashing,也称开地址法,opened addressing。

  • 相关阅读:
    el-select下拉框选项太多导致卡顿,使用下拉框分页来解决
    vue+elementui前端添加数字千位分割
    Failed to check/redeclare auto-delete queue(s)
    周末啦,做几道面试题放松放松吧!
    idea快捷键
    解决flink运行过程中报错Could not allocate enough slots within timeout of 300000 ms to run the job. Please make sure that the cluster has enough resources.
    用.net平台实现websocket server
    MQTT实战3
    Oracle 查看当前用户下库里所有的表、存储过程、触发器、视图
    idea从svn拉取项目不识别svn
  • 原文地址:https://www.cnblogs.com/hwtblog/p/9604132.html
Copyright © 2011-2022 走看看