哈希表查找

前面查找方法的共同特点:通过关键字值与给定值进行比较,来确定位置。效率取决于比较次数。理想的方法是:不需要比较,根据给定值能直接定位记录的存储位置。这样需要在记录的存储位置与该记录的关键字之间建立一种确定的对应关系,使每个记录的关键字与一个存储位置相对应。

哈希表的特点和结构


hashtable也叫做散列表,有多种结构,其中最常见的是采用顺序表+链表,主结构采用顺序表,每个顺序表的节点单独引出一个链表。

哈希表是如何添加数据的
  1. 计算哈希码(调用hashCode()函数,结果是一个int型的值,整数的哈希码取自身即可)
  2. 计算在哈希表中的存储位置y=k(x)=x%11 x:哈希码 k(x)函数、y:在哈希表中的存储位置。
  3. 存入哈希表
    情况一:一次性添加成功
    情况二:多次添加成功(出现了冲突,调用equals()函数和对应链表的元素比较,若比较到链表结尾,返回结果都是false,创建新的节点存储数据,并加入链表末尾)
    情况三:不添加数据(出现了冲突,调用equals()函数和对应链表的元素比较,经过一次或者多次比较后,返回结果为true,表明数据已经在表中,不添加)

【将以下数据加入Hash表】

由于要加入Hash表中的元素为数字,数字的哈希码为其本身,通过y=k(x)=num%11取得每个数字在哈希表中的存储位置,将其加入,在向表中加入17时发现位置1已经存在数据,因此产生了冲突。

当产生冲突时,调用equals()方法与当前位置元素依次比较,若比较到链表结尾,返回结果都是false,创建新的节点存储数据并加入链表末尾。

哈希表添加数据非常快,3步即可,唯一、无序

哈希表是如何查询数据的

哈希表查询数据与添加过程相同
情况一:一次找到:23 86 76
情况二:多次找到:67 56 79
情况三:找不到:100 200

哈希表查询数据非常快,更新数据也非常快(如果更新影响到哈希码,就变得烦琐了,要先删除节点在添加)

hashCode()和equals()到底有什么神奇的作用

hashCode():计算哈希码,是一个整数,根据哈希码可以计算出数据在哈希表中的存储位置。
equals():添加时出现了冲突,需要通过equals()进行比较,判断是否相同,查询时也需要使用equasl()进行比较,判断是否相同。

如何减少冲突
  1. 哈希表的长度和表中的记录数的比例–装填因子:
    如果哈希表的空间远远大于最后实际存储的记录个数,则造成了很大的空间浪费,如果选取小了的话,则容易造成冲突。在实际情况中,一般需要根据最终记录存储个数和关键字的分布特点来确定Hash表的大小。还有一种情况是可能事先不知道最终需要存储的记录个数,则需要动态维护hash表的容量,此时可能需要重新计算Hash地址。
    装填因子=表中的记录数/哈希表的长度
    如果装填因子越小,表明表中还有许多空单元,则添加发生的冲突的可能性越小;而装填因子越大,则发生冲突的可能性越大,在查找时所消耗的时间越多,因此,一般情况下,装填因子取经验值0.5
  2. 哈希函数的选择:
    直接定址法、平方取中法、折叠法、除留取余法(y=x%11)
  3. 冲突的处理办法:
    链地址法、开放地址法、再散列法、建立一个公共溢出区
Java中的Hash表查找

Java中的HashSet和HashMap的底层都使用了哈希表HashTable。
HashSet的源码分析:

    private transient HashMap<E,Object> map;
    
    private static final Object PRESENT = new Object();
    
    public HashSet() {
        map = new HashMap<>();
    }

由源码可以发现,HashSet的底层为HashMap,并且将值存储在HashMap的key中,HashMap的value为new Object()即为空。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值