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函数。

2018-08-27_第1张图片
String的hashCode

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

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

Boolean的hashCode

你可能感兴趣的:(2018-08-27)