美文网首页程序员
散列表(中)

散列表(中)

作者: 二毛_220d | 来源:发表于2018-12-30 19:27 被阅读4次

如何设计这样一个工业级散列表呢?我会从3个方面来考虑设计思路:

1.设计一个合适的散列函数;
2.定义装载因子阈值,并且设计动态扩容策略;
3.选择合适的散列冲突解决方法。

一、如何设计散列函数?

1.要尽可能让散列后的值随机且均匀分布,这样会尽可能减少散列冲突,即便冲突之后,分配到每个槽内的数据也比较均匀。
2.除此之外,散列函数的设计也不能太复杂,太复杂就会太耗时间,也会影响到散列表的性能。
3.常见的散列函数设计方法:直接寻址法、平方取中法、折叠法、随机数法等。

二、如何根据装载因子动态扩容?

如何设置装载因子阈值?

1.可以通过设置装载因子的阈值来控制是扩容还是缩容,支持动态扩容的散列表,插入数据的时间复杂度使用摊还分析法。
2.装载因子的阈值设置需要权衡时间复杂度和空间复杂度。如何权衡?如果内存空间不紧张,对执行效率要求很高,可以降低装载因子的阈值;相反,如果内存空间紧张,对执行效率要求又不高,可以增加装载因子的阈值。

如何避免低效扩容?分批扩容

1.分批扩容的插入操作:当有新数据要插入时,我们将数据插入新的散列表,并且从老的散列表中拿出一个数据放入新散列表。每次插入都重复上面的过程。这样插入操作就变得很快了
2.分批扩容的查询操作:先查新散列表,再查老散列表。
3.通过分批扩容的方式,任何情况下,插入一个数据的时间复杂度都是O(1)。


分批搬移数据

三、如何选择散列冲突解决方法?

  • 常见的2中方法:开放寻址法和链表法。
  • 大部分情况下,链表法更加普适。而且,我们还可以通过将链表法中的链表改造成其他动态查找数据结构,比如红黑树、跳表,来避免散列表时间复杂度退化成O(n),抵御散列冲突攻击。
  • 但是,对于小规模数据、装载因子不高的散列表,比较适合用开放寻址法。

分析Java的HashMap:

初始大小

hashMap默认的初始大小是16.

装载因子和动态扩容

最大装载因子默认为0.75,当hashMap中元素个数超过0.75*capacity(capacity表示散列表的容量)的时候,就会启动扩容。每次扩容都会扩容到原来的两倍。

散列冲突解决方法

使用单链表解决hash冲突,当链表长度大于8,将单链表转换成红黑树 , 当链表长度小于6,将红黑树退化为单链表。

散列函数

hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

相关文章

  • 散列表中

    如何设计散列函数 散列函数的设计不能太复杂 散列函数生成的值要尽可能随机并且均匀分布 装载因子过大了怎么办? 对于...

  • 散列表(中)

    如何设计这样一个工业级散列表呢?我会从3个方面来考虑设计思路: 1.设计一个合适的散列函数;2.定义装载因子阈值,...

  • 散列表中

    如何设计散列函数 散列函数的设计不能太复杂 散列函数生成的值要尽可能随机并且均匀分布 装载因子过大了怎么办? 对于...

  • 算法图解-散列表

    1. 散列表 散列表由键和值组成,散列表将键映射到值。 在复杂数据结构中,散列表可能是最有用的,也被称为散列映射、...

  • java中关于散列表的详细介绍

    java中关于散列表的详细介绍 什么是散列表 散列表,也叫作哈希表(Hash Table),是一种提供键(Key)...

  • java中关于散列表的详细介绍

    java中关于散列表的详细介绍 什么是散列表 散列表,也叫作哈希表(Hash Table),是一种提供键(Key)...

  • 散列表(中):如何打造一个工业级水平的散列表?

    散列表(中):如何打造一个工业级水平的散列表? 上一篇中,我们了解到,散列表的查询效率并不能笼统地说成是 ○(1)...

  • 散列表

    散列表又称 hash 表 散列表底层是一个数组,数组中存放的是(key,value),它本质是空间换时间 散列表是...

  • 散列表(中)如何打造工业级散列表

    散列表的查询效率并不能笼统地说成是O(1)。它跟散列函数、装载因子、散列冲突等都有关系。如果散列函数设计得不好,或...

  • 散列表

    散列表 认识散列表 是 字典(键 、值对)的一种实现方式。每次在字典中获取一个值,都需要重复遍历字典,如果用散列表...

网友评论

    本文标题:散列表(中)

    本文链接:https://www.haomeiwen.com/subject/efxblqtx.html