什么是Hash表

1.定义

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

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

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

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

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

3.基本原理及要点

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

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

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

open live writer 测试的更多相关文章

  1. Windows Live Writer测试

    第一次使用Windows Live Writer,一堆问题,不知道是中国强大的局域网防火墙问题还是咋的,弄了半天. 1.C++的测试代码: int _tmain(int argc, _TCHAR* a ...

  2. Windows Live Writer测试插件

    这是用WLW写的,测试 这是图片: 这是地图: 这是代码: 一会重发

  3. Open Live Writer测试

    ************************我是可爱的分界线***************************

  4. Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话.输入的语句是如何变成搜索条件的上一篇已经略有提及. 4.3.1 观察 ...

  5. Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个 ...

  6. xStream转换XML、JSON

        一. 简介 xStream可以很容易实现Java对象和xml文档互相转换, 可以修改某个特定的属性和节点名称,xStream提供annotation注解, 可以在JavaBean中完成对xml ...

  7. Windows Live Writer发布测试

    通过Windows Live Writer发布文章测试!!!!

  8. 测试使用Windows Live Writer

    目前是在win7系统下面使用的,曾经在winxp下去配置,却失败了,难道不支持xp? Windows Live Writer好像不支持代码关键字高亮显示啊. int main(void) { prin ...

  9. 测试 windows live writer

    This is the first article written by the writer!   wenzhaoshanda

随机推荐

  1. 知识小罐头08(tomcat8启动源码分析 上)

    前面好几篇都说的是一个请求是怎么到servlet中的service方法的,这一篇我们来看看Tomcat8是怎么启动并且初始化其中的组件的? 相信看了前面几篇的小伙伴应该对Tomcat中的各个组件不陌生 ...

  2. Windows下SVN服务器搭建和基本操作(服务端、客户端)

    自己打算打一个SVN服务器了解一下,所以顺便记录一下整个的过程 下载 服务端 https://www.visualsvn.com/server/download/ 客户端 https://www.vi ...

  3. Sentinel 流程分析

    最近公司开始做新的项目.新项目准备用点新的技术.之前我们采用的是spring cloud的那一套.之前几个月看到阿里开始拥抱springcloud,推出好几个组件无缝兼容现有springcloud.我 ...

  4. 卷积神经网络 CNN 学习笔记

    激活函数Relu 最近几年卷积神经网络中,激活函数往往不选择sigmoid或tanh函数,而是选择relu函数.Relu函数的定义 $$f(x)= max(0,x)$$ Relu函数图像如下图所示: ...

  5. Win32对话框程序(2)

    接着Win32对话框程序(1)来写 ,解决遗留的问题,即理解函数及其调用关系.文章中有些地方是自己的推断,因此肯定有叙述不准确甚至错误的地方,请指正,感谢~ ********************* ...

  6. Docker最全教程——MongoDB容器化(十二)

    MongoDB容器化 MongoDB是一个免费的.开源的.跨平台分布式面向文档存储的数据库,由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和 ...

  7. cocos creator主程入门教程(五)—— 日志系统

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍日志系统的设计.一般我们开发一个demo,只会简单的用cocos提供的cc.log打印下日志, ...

  8. leetcode math类型题目解题总结

    2. Add Two Numbers https://leetcode.com/problems/add-two-numbers/description/ class Solution { publi ...

  9. sublime text3插件解决输入法不跟随的问题

    快捷键ctrl + shift +p 输入  install package 回车,调出插件搜索器, 在搜索栏中输入 IMESupport 回车安装插件. 即可解决问题.

  10. Microsoft.Office.Interop.Excel 报错

    Microsoft.Office.Interop.Excel 报错 引用dll 在以下目录 C:\Windows\assembly\GAC_MSIL\Microsoft.Office.Interop. ...