散列表(中)

作者 : 开心源码 本文共991个字,预计阅读时间需要3分钟 发布时间: 2022-05-12 共165人阅读

如何设计这样一个工业级散列表呢?我会从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);}

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 散列表(中)

发表回复