数据结构之哈希表
数据结构之哈希表
一、基础
1、简介
(1)每一个字符和一个索引相对应
(2)哈希函数:“键”转换为“索引”
(3)哈希冲突 : 很难保证每一个“键”通过哈希函数的转换对应不同的“索引”
2、特点
(1)哈希表体现了空间换时间的思想,是时间和空间之间的平衡
(2)哈希函数的设计是很重要的,“键”通过哈希函数得到的“索引”分布越均匀越好
二、哈希函数的设计
1、整型
小范围正整数直接使用,小范围负整数进行偏移
2、大整数
(1)通常做法:取模,哈希表越大,冲突越小
(2)简单的解决办法:模一个素数
3、浮点型
在计算机中都是32位或者64位的二进制表示,只不过计算机解析成了浮点数,可以转换成整型处理
4、字符串
转成整型处理
Code=c*26^3+o*26^2+d*26^1+e*26^0:26进制的整型
code=c*B^3+o*B^2+d*B^1+e*B^0 :B进制的整型
Hash(code)=(c*B^3+o*B^2+d*B^1+e*B^0)%M
转成整型处理,并不是唯一的方法
5、设计原则
(1)一致性:如果a==b,则hash(a)==hash
(2)高效性:计算高效简便
(3)均匀性:哈希值均匀分布
三、哈希冲突
1、链地址法Seperate Chaining
(1)将重复地址的元素形成链表
(2)HashMap是一个TreeMap数组 ; HashSet是一个TreeSet数组
(3)Java8之前,每一个位置对应一个链表
Java8开始,当哈希冲突达到一定程度,每一个位置从链表转成红黑树
2、复杂度分析
(1) M个地址,向哈希表放入N个元素,如果每个地址是链表,则O(N/M), 如果每个地址是平衡树, 则 O(log(N/M))
(2) 均摊复杂度位O(1)
(3) 牺牲了顺序性
3、优化
(1)动态,平均每个地址承载的元素多过一定程度,即扩容
(2)平均每个地址承载的元素少过一定程度,即缩容
4、哈希冲突处理方法
(1)开放地址法—每一个地址存一个元素,起冲突则找下一个位置
平方探测,遇到哈希冲突,+1+4+9+16
二次哈希法,遇到哈希冲突,+hash2(key)
(2)再哈希法Rehashing
5、集合和映射
(1)有序集合、有序映射----平衡树
(2)无序集合、无序映射----哈希表