散列表(哈希表)

1、概述

集合中的元素按以下两种顺序之一排列:

  • 其顺序由往集合添加和(或)从集合中删除元素的顺序决定,如栈、队列、无序列表和索引表
  • 其顺序由比较元素(或是元素的某个关键字部分)的值决定,如有序列表和二叉查找树

在散列中,元素被存储在一个散列表中,他们在散列表中的位置由一个散列函数决定。散列表中的每个位置可以称为单元(cell)或桶(bucket)。

与集合的实现不同,使用散列方法访问特定元素的时间与散列表中的元素数目无关,时间复杂度都是O(1)。但是只有当每个元素都映射到散列表中独特位置时,其效率才会得到完全体现。将每个元素映射到散列表中独特位置的散列函数称为完美散列函数。两个元素或关键字映射到散列表中相同位置的情况称为冲突(collision)。

散列表的大小:

  • 如果已知数据集合的大小并且可以运用完美散列函数,那么只需将散列表设置为数据集合的大小。
  • 如果完美散列函数根本不存在或者不适用,但数据集合的大小已知,将散列表的大小设置为数据集合大小的1.5倍。
  • 如果不知道数据集合的大小,要动态改变散列表的大小。一种是散列表满的时候才扩大,但当散列表满时其性能严重下降。一种是使用负载因子(load factor)。

2、散列函数

  • 余数法:把关键字除以一个正整数的余数作为给定元素的索引。
  • 折叠法:把关键字分割成多个部分,再组合或叠加到一起创建散列表的索引。
  • 平方取中法:平方后,取中间合适的位数作为索引。
  • 基数转换法:将关键字转换为另一种进制,再用余数法。
  • 数字分析法:索引是通过抽取、处理关键字指定数位来生成的。
  • 长度相关法:关键字和关键字的长度用某种方式绑定

3、解决冲突

  • 链地址法:链地址法有多种实现方式。
  1. 让保存散列表的数组大于散列表的单元数,把多余的空间作为溢出区。在这中方式中,数组每个位置同时存储了一个元素以及下一个元素的数组索引
  2. 使用链表
  3. 将散列表每个位置作为一个指针,指向一个集合
  • 开发地址法
  1. 线性探测法:如果一个元素散列到位置p而p已经被占用,就尝试位置(p+1)%s,这里s是散列表的大小,直到找到一个空位置或回到p为止。
  2. 二次探测法:newhashcode(x) = hashcode(x) +((-1)^(i-1))*(((i+1)/2)^2),i从1到s-1。查找序列为p、p+1、p-1、p+4、p-4...

4、删除元素:根据实现方式删除元素

5、Java集合API中的散列表

  • Hashtable
  • HashSet
  • HashMap
  • IdentityHashMap
  • WeakHashMap
  • LinkedHashSet与LinkedHashMap等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值