散列表和散列函数

2020-10-21  本文已影响0人  文景大大

一、什么是散列表

散列表是由数组扩展而来,其通过散列函数将元素的键值映射为下标,然后将元素存储在数组中对应下标的位置。

关键字经过散列函数的计算得到一个散列值:hash(key)=hashCode;关于散列函数的选择和设计,应该要满足如下三个要求:

这三个条件中,最难满足的就是第三点,在现实中找一个这样的散列函数几乎是不可能的;比如著名的hash算法MD5、SHA、CRC等,都只是尽量均匀地散列,尽量避免散列冲突,但是做不到完全避免;而且由于数组空间有限,散列冲突就太正常不过了。

二、如何处理散列冲突

2.1 开放寻址法

2.2 链表法

该种方法中,每个位置(可以称为桶、槽)对应一个链表,所有散列值相同的元素都放在该位置对应的链表中,结构示意图如下:

链表发解决散列冲突示意

当需要插入元素的时候,直接找到对应下标的插槽,插入链表即可,时间复杂度为O(1);

当需要查找和删除元素的时候,也是找到对应下标的插槽,然后遍历链表查找即可,时间复杂度为O(n/m),n是当前元素的个数,m是数组大小,假设散列是均匀的,那么时间复杂度就是链表的长度;

无论插入、查找还是删除,时间复杂度都要优于开放寻址法;

适用场景:

当需要存储的数据比较多,或者存储的是大对象的时候,链表法比较合适,而且链表的长度过长时可以采用灵活的优化策略,比如红黑树来代替链表,如此查找时间复杂度最坏情况下的O(n)就能优化为O(logn);

2.3 装载因子

装载因子=已经装入散列表中的元素个数/散列表总的位置个数

装载因子是用来衡量散列表当前盈满程度的指标,其越大,说明散列冲突的概率就越高,当达到一定程度,就需要对散列表进行扩容了。

开放寻址法中,装载因子不会超过100%,但是在拉链法中,装载因子是会超过100%的;

三、散列函数的设计

四、散列表HashMap分析

五、散列表LinkedHashMap分析

也是通过散列表和链表组合在一起实现的,只不过此处的链表不是单链表,而是双向链表,可以用来记录元素插入的顺序。

上一篇 下一篇

猜你喜欢

热点阅读