2018-08-27

浅谈数据结构中Hash

Hash在中文中有时被称作“散列”,也有时直接叫“哈希”。

基本概念:给定一个值(Key),进过 hash函数(f)映射成 hash值(f(key))。再深入点,将一个范围A,映射成一个范围B,每个范围A中的值都有一个范围B的值相对应。一般来说,范围A的大小 大于  范围B。

一般来说hash值是一个正整数。

应用:hash表(散列表):hash表作为一种数据结构,它通过把值映射到表中一个位置来访问记录,以加快查找的速度。举例,对于一组有n个数据的数据集,如果在其中寻找一条记录,最普遍的方法是一条条遍历,时间复杂度就是O(n),最坏的情况需要查找n次,而应用hash表,那么只要知道查找值的hash值,那么一般情况下只需要查找一次,也就是O(1)。

当然上面也说了,范围A > 范围B,自然会出现一种状况,两个不同的key的hash值相同。这玩意叫碰撞,或者冲突。

冲突解决方法:

1、建立一个缓冲区,当冲突发生时,后来的key放入缓冲区,之后如果根据hash值找到的key错误时,那去缓冲区查找。

2、再次散列

(1) 线性探测:如果冲突了,那么查找该hash值之后的一个位置有没有记录,没有就放在这个位置,有就接着往后面探测,直到找到一个空位。也就是说每次hash值+1。

(2)二次探测:和线性探测不同,二次探测的话,hash值每次+( ±(i^2)),i=1,2,3...m/2,m是hash表的长度,或者说范围B的大小。相较于线性探测,二次探测可以使得记录分布更加均匀。

(3)再散列:采用别的hash函数,取得不同的hash值

3、链地址法(拉链法):每一个hash值的位置对应一个链表,那就可以存储多个值了。(java中的hashmap就是采用这种方式)

hash函数:我这就不说了,常用的就是直接对key取余,乘法等等,也可以自己设计散列函数。

在JAVA中呢,Object有一个hashCode函数可以获取,对象的hashCode,但Objet没有具体实现这个方法。

Object的hashCode

那就看看String中的hashCode,它用的乘法hash函数。

String的hashCode

先说一下,如果int和char相加,那么char会取它的ascll码。

再看一下Boolean的hashCode,返回1231或者1237。

Boolean的hashCode
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 博客github仓库更新代码指令笔记 本笔记包含两大部分,第一部分为更新github常用指令,第二部分为引用博客,...
    __tudou__阅读 652评论 0 1
  • 一、 1、递归函数: 2、数组: 3、数组的遍历: 4、数组对象方法: 二、此处为从网上获取的比较全的数组对象的使...
    Simon_s阅读 1,291评论 0 1
  • 我们每天都在经历着非常多的事情,看一部电影,读一本书,吃一顿饭,见一个人。随着太阳升起,崭新的一天开始,随着夕阳西...
    Mango呵阅读 162评论 0 0