散列表

散列表

1.原理:基于数组下标可随机访问原理,用于快速查询某个数据,时间复杂度O(1),但不绝对,跟装载因子,散列函数,冲突函数啥的都有关系

组成:table=Hash(key),key是原始值,table表示经过哈希处理的哈希值,Hash表示哈希函数,是table 与key的一种映射关系.

散列函数选取原则:散列函数得到的值非负;对于key1=key2,Hash(key1)==Hash(key2),同样的,对于

key1!=key2,Hash(key1)!=Hash(key2)

2.散列冲突解决办法

(1)链表法:冲突的部分放那个位置,加链表扩展位置

(2)开放寻址法:hash后的位置被占用,则挪到其他位置。比如线性探测(遇到冲突,table=Hash(key)+0,table=Hash(key)+1,table=Hash(key)+2 往后移一位,直到遇到空位置),二次探测(table=Hash(key)+0,table=Hash(key)+12,table=Hash(key)+22),双重散列(两个hash函数,一个冲突用另一个)

装载因子=填入表中的元素个数/表的长度,表征散列表空位程度,越大空位越小。

3.两种方法的对比

(1)链表法:对内存运用率高,开放地址装载因子只能小于等于1,而链表法装载因子很大只是链表变长而已。但存储链表需要指针,对小对象耗内存,但大对象可以忽略这一点,而且链表占据内存不连续,对CPU不友好。适合大对象大数据量,而且可以进一步优化为红黑树,如LinkedHashMap(这个数据结构是用散列表和双向链表结合实现的,LRU机制)

(2)开放地址法:可以利用CPU缓存加快速度,序列化比较容易,但冲突发生几率高,处理冲突比较麻烦,负载因子不能过大,占用空间大。数据小装载因子小的时候,适合用开放地址办法,如ThreadLocalMap

几个处理的小方法:

(1)删除时,不是真的删除,而是标记为deleted,这样再查找时不会破坏原有的结构

(2)遇到扩容出了新数组,在插入时,有时数据太大不能忍受搬迁的过程,可以插入一个数据的同时搬迁原数组的数据,慢慢搬移,这样每个数据插入的时间复杂度依然是O(1),这样在查找时,就应该现在新数组查找,找不到再去原数组查找

JAVA实例:HashMap

初始大小16,

装载因子 0.75,

动态扩容一次扩大为原来的二倍,

冲突解决方法:链表法,JDK1.8后,链表长度大于8用红黑树,小于8自动退化为链表

散列函数:

int hash(Object key) {    
	int h = key.hashCode();    
	return (h ^ (h >>> 16)) & (capitity -1); //capicity 表示散列表的大小 
}

4.哈希算法:

散列表是哈希算法的一个应用,其他的还有数字摘要,安全加密,还有判断信息完整性的作用。

哈希一致性用于解决扩容时搬迁大量数据问题

https://www.sohu.com/a/158141377_479559

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值