散列表,哈希表,hash表,Hashtable 都是同一个概念
1. 散列表来源于数组,它借助散列函数对数组这种数据结构进行扩展,利用的是数组支持按照下标随机访问元素的特性。
2. 散列函数,即通过一个方法让hash(key)尽可能均匀的分布到预置容器长度内,但几乎不可能避免散列冲突。散列函数的设计不能太复杂。过于复杂的散列函数,势必会消耗很多计算时间,也就间接地影响到散列表的性能。其次,散列函数生成的值要尽可能随机并且均匀分布,这样才能避免或者最小化散列冲突,而且即便出现冲突,散列到每个槽里的数据也会比较平均,不会出现某个槽内数据特别多的情况。
3. 解决散列冲突的办法,一是寻址法(核心思想是:如果出现散列冲突,就重新探测一个空闲位置,将其插入),二是更常用的链表法(插入的时候,我们需要通过散列函数计算出对应的散列槽位,将其插入到对应的链表中即可)。
4. 装载因子(load factor)散列表的装载因子=填入表中的元素个数 / 散列表的长度, 装载因子越大,说明空闲位置越少,冲突越多,散列表的性能会下降。
一般如果装载因子达到阈值,需要对散列表动态扩容,同时也会涉及到数据的搬迁,因为散列表的大小变了,数据的存储位置也变了,所以我们需要通过散列函数重新计算每个数据的存储位置。
5. 工业级散列表的要求
a. 合理的散列函数,简单,不占用太多cpu时间,让hash(key)尽量少发生碰撞
b. 合适的初始值,比如java中HashMap,默认是16个,如果知道数据量多少,可以指定合适的初始值,避免频繁搬迁数组
c. 合适的装载因子,比如0.75阈值只有启动动态扩容
d. 散列冲突解决,链表法,但数据量很大是,java会采用红黑树结构来加快查询和删除,提高性能,但数据量少于8个时,又退化为简单的链表结构。
6. 应用
a. 负载均衡
b. 数据分片
c. 如何快速判断图片是否在图库中?
d. 分布式存储
原文:https://www.cnblogs.com/roy1/p/13568836.html