哈希表与哈希值

哈希表是一种数据结构,它可以提供快速的插入和查找操作。不管哈希表中有多少数据,插入和删除时间都是接近常量的时间:即O(1)。
缺点是:它是基于数组的,数组创建后难以扩展,哈希表被基本填满时,性能下降严重,而且不能够顺序遍历数据。

由于哈希表是基于数组的,所以就要把关键字转化成数组下标。
哈希函数负责把大范围的数字(由关键字计算得出)转换成小范围的数字。这个小范围的数字对应着数组下标。

转化时会碰到一个问题:不是数组每个位置都有值,也不是每个位置都保证只有一个值。
当冲突发生时,一个方法是通过系统的方法找到数组的一个空位,把这个数据填入,而不再用哈希函数得到的数组下标,这个方法叫做开放地址法
第二种方法是创建一个存放数据的链表的数组,这样当冲突发生时新的数据项直接接到数组下标所指的链表中。这种方法叫链地址法


java中object类的hashCode方法,默认返回的一般不是对象的地址,具体hashCode与jvm实现有关(C++实现的ObjectSynchronizer::FastHashCode调用get_next_hash方法计算hash值)。
大多数对象默认的hashCode意义不大,比如整数的hash值就是整数本身。
如果重写了对象的equals方法,一般也要重写hashCode方法,保证相等。
推测:保证对象相等时哈希值一致的目的,是为了hashSet,hashMap,hashtable等hash体系的数据结构具有高效的性能。

hash值需要遵守的约定:
  • 一致性(consistent),在程序的一次执行过程中,对同一个对象必须一致地返回同一个整数。
  • 如果两个对象通过equals(Object)比较,结果相等,那么对这两个对象分别调用hashCode方法应该产生相同的整数结果。
  • 如果两个对象通过java.lang.Object.equals(java.lang.Ojbect)比较,结果不相等,不必保证对这两个对象分别调用hashCode也返回两个不相同的整数。

开放地址法

在开放地址法中,若数据不能直接放在由哈希函数计算出来的数据下标所指的单元时,就需要寻找数组的其它位置。下面介绍探索开放地址的三种方法:线性探测、二次探测和再哈希法。

线性探测

如果542是要插入的位置,而它已经被占用了,那么就插入543,依次递增。
待续。,。

猜你喜欢

转载自blog.csdn.net/ljz2016/article/details/82911164