【Java数据结构】哈希表详解

**闭散列:**也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那么可以 把key存放到冲突位置中的“下一个” 空位置中去。

①线性探测


比如上面的场景,现在需要插入元素44,先通过哈希函数计算哈希地址,下标为4,因此44理论上应该插在该 位置,但是该位置已经放了值为4的元素,即发生哈希冲突。 线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。

插入

通过哈希函数获取待插入元素在哈希表中的位置 如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探测找到 下一个空位置,插入新元素

采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素,若直接删除元素会影响其他 元素的搜索。比如删除元素4,如果直接删除掉,44查找起来可能会受影响。因此线性探测采用标 记的伪删除法来删除一个元素。

②二次探测


线性探测的缺陷是产生冲突的数据堆积在一块,这与其找下一个空位置有关系,因为找空位置的方式就是挨 着往后逐个去找,因此二次探测为了避免该问题,找下一个空位置的方法为: = ( + )% m, 或者: = ( - )% m。其中:i = 1,2,3…, 是通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置, m是表的大小。 对于2.1中如果要插入44,产生冲突,使用解决后的情况为:

研究表明:当表的长度为质数且表装载因子a不超过0.5时,新的表项一定能够插入,而且任何一个位置都不 会被探查两次。因此只要表中有一半的空位置,就不会存在表满的问题。在搜索时可以不考虑表装满的情 况,但在插入时必须确保表的装载因子a不超过0.5,如果超出必须考虑增容。

5,冲突-解决-开散列/哈希桶

===================

开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子 集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。

static class Node {

public int key;

public int val;

public Node next;

public Node(int key, int val) {

this.key = key;

this.val = val;

}

}

private Node[] array;

public int usedSize;

public HashBucket() {

this.array = new Node[10];

this.usedSize = 0;

}

public void put(int key,int val){

int index = key % this.array.length;

Node cur = array[index];

while (cur != null){

if(cur.val == key){

cur.val = val;

return;

}

cur = cur.next;

}

//头插法

Node node = new Node(key,val);

node.next = array[index];

array[index] = node;

this.usedSize++;

if(loadFactor() >= 0.75){

resize();

}

}

public int get(int key) {

//以什么方式存储的 那就以什么方式取

int index = key % this.array.length;

Node cur = array[index];

while (cur != null) {

if(cur.key == key) {

return cur.val;

}

cur = cur.next;

}

return -1;//

}

public void resize(){

Node[] newArray = new Node[2*this.array.length];

for (int i = 0; i < this.array.length; i++){

Node cur = array[i];

Node curNext = null;

while (cur != null){

curNext = cur.next;

int index = cur.key % newArray.length;

cur.next = newArray[i];

newArray[i] = cur;

cur = curNext.next;

cur = curNext;

}

}

this.array = newArray;

}

6,完整代码

==========

class HashBucket {

static class Node {

public int key;

public int val;

public Node next;

public Node(int key, int val) {

this.key = key;

this.val = val;

}

}

private Node[] array;

public int usedSize;

public HashBucket() {

this.array = new Node[10];

this.usedSize = 0;

}

public void put(int key,int val) {

//1、确定下标

int index = key % this.array.length;

//2、遍历这个下标的链表

Node cur = array[index];

while (cur != null) {

//更新val

if(cur.key == key) {

cur.val = val;

return;

}

cur = cur.next;

}

//3、cur == null 当前数组下标的 链表 没要key

Node node = new Node(key,val);

node.next = array[index];

array[index] = node;

this.usedSize++;

//4、判断 当前 有没有超过负载因子

if(loadFactor() >= 0.75) {

//扩容

resize();

}

}

public int get(int key) {

//以什么方式存储的 那就以什么方式取

int index = key % this.array.length;

Node cur = array[index];

while (cur != null) {

if(cur.key == key) {

return cur.val;

}

cur = cur.next;

}

return -1;//

}

public double loadFactor() {

return this.usedSize*1.0 / this.array.length;

}

public void resize(){

Node[] newArray = new Node[2*this.array.length];

for (int i = 0; i < this.array.length; i++){

Node cur = array[i];
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。

《Java高级面试》

《Java高级架构知识》

《算法知识》

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mages/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后

分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。

《Java高级面试》

[外链图片转存中…(img-R0qLR21z-1713527517694)]

《Java高级架构知识》

[外链图片转存中…(img-wPa9W4gm-1713527517695)]

《算法知识》

[外链图片转存中…(img-5THRCTDp-1713527517697)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值