1、非线性表之哈希表(散列表)

  1. 1、散列表-概述
  2. 1-1、散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
  3. 1-1-1、这个映射函数叫做散列函数/哈希函数,存放记录的数组叫做散列表/哈希表。
  4. 1-1-2、每个关键字被映射到0到数组大小N-1范围,并且放到合适的位置,这个映射规则就叫散列函数
  5. 1-2、散列/哈希碰撞/冲突
  6. 1-2-1、关键字范围可能远超数组单元,因此就会出现两个关键字散列到同一个值得时候
  7. 1-2-2、解决方式
  8. -- 开地址法:数组中重新找位置保存数据(如果冲突发生,就选择另外一个可用的位置)
  9. -- 线性探测法-策略
  10. -- 平方探测法-策略
  11. -- 双散列-策略
  12. -- 拉链法:形成链表(将同一个值的关键字保存在同一个表中)
  13. -- 再散列

1.1、哈希冲突

  1. 1、哈希表的实现
  2. 1-1、哈希表本质就是一个数组
  3. 1-2、实现哈希表我们可以采用两种方法:
  4. 1-2-1、数组 + 链表
  5. 1-2-2、数组 + 二叉树
  6. 2、哈希冲突/哈希碰撞处理:
  7. 2-1、链地址法
  8. 2-1-1、当哈希冲突达到了一定的程度,java7为链表,java8是红黑树。
  9. 2-2、开放地址法,比如:ThreadLocal
  10. 2-2-1、当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止。
  11. -- 用公式描述为:
  12. H i ( key ) = ( H ( key )+ d i ) mod m ( i = 1,2,…… k ( k m 1))
  13. 其中: H ( key ) 为关键字 key 的直接哈希地址, m 为哈希表的长度, di 为每次再探测时的地址增量。
  14. 用这种方法时,首先计算出元素的直接哈希地址 H ( key ) ,如果该存储单元已被其他元素占用,则继续查看地址为 H ( key ) + d 2 的存储单元,如此重复直至找到某个存储单元为空时,将关键字为 key的数据元素存放到该单元。
  15. 增量 d 可以有不同的取法,并根据其取法有不同的称呼:
  16. -- d i 1 2 3 …… 线性探测再散列;
  17. -- d i 1^2 ,- 1^2 2^2 ,- 2^2 k^2 -k^2…… 二次探测再散列;
  18. -- d i 伪随机序列 伪随机再散列;