Java数据结构_hash

本文详细介绍了Java中的哈希算法,包括概念、常用函数和解决碰撞的方法。在哈希数据结构部分,文章重点讲解了HashMap的内部机制,如数组+链表+红黑树的结构,以及何时转化为红黑树。此外,还提到了HashMap的扩容策略、线程不安全的原因以及查找过程。同时,文章对比了HashSet和HashMap的异同。
摘要由CSDN通过智能技术生成


一、hash算法

1.概念

hash(散列)
更像是一种思想而不是算法,它把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

哈希碰撞
一般来说,根据同一个哈希函数得到的散列值如果不同,则输入值一定不同,但存在输入值不同,根据同一个哈希函数得到相同的散列值的情况,此时就发生了哈希碰撞。
由于散列值的空间远小于输入值空间,所以哈希碰撞是无法避免的,但是可以通过其他方法尽量避免或解决。

2.常用函数

哈希函数

  1. 直接寻址法:
    直接以关键字k或者k加上某个常数(k+c)作为哈希地址。这种方法不会产生碰撞,但散列值空间==输入值空间,所以很少使用。
  2. 数学分析法:
    提取关键字中取值比较均匀的数字作为哈希地址。这种方法需要在放入前知道所有关键字的信息才能进行提取,所以不常使用。
  3. 平方取中法:
    如果关键字各个部分分布都不均匀的话,可以先求出它的平方值,然后按照需求取中间的几位作为哈希地址。因为中间几位的取值与每位数字都有关,所以通常会分布不同。
  4. 随机数法:
    选择一个随机函数,取关键字的随机函数值作为Hash地址 ,通常用于关键字长度不同的场合。
  5. 除留取余法:
    取关键字被某个不大于Hash表 长m 的数p 除后所得的余数为Hash地址 。较为常用。

解决函数

  1. 开放定址法:
    开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。

  2. 链地址法(拉链法)
    将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。即发生冲突时就把该关键字链在以该单元为头结点的链表的尾部。HashMap用这种方法

  3. 再哈希法
    当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止。

  4. 建立公共溢出区
    将哈希表分为基本表和溢出表两部分,发生冲突的元素都放入溢出表中。

二、hash的数据结构

1.HashMap

HashMap 是 Map 接口的常用实现类,本质还是一个键值对的对象,每个记录就是一个Entry<K, V>对象࿰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值