哈希桶(详解&创建)

简介: 哈希桶(详解&创建)

一、什么是哈希桶?


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

image.png

编辑

如图,哈希是数组+链表结构,按照传入的元素放在通过散列函数计算出的散列地址处,如果再加入新的相同散列地址则向后通过链表将其链接在一起。

二、创建哈希桶


2.1创建节点以及哈希表。


key:关键码通过散列函数计算出的散列地址

val:节点对应的值

next:向后链接相同散列地址的节点地址

image.png

节点的创建:

static class Node {
    public int key;
    int val;
    Node next;
    public Node(int key,int val) {
        this.key =key;
        this.val = val;
    }
}
public Node[] array;

散列表的创建:

public Node[] array;
public int usedsize;

这里需要了解一个概念:

负载因子:x = 填入表中元素的个数 / 散列表的长度。

负载因子过高会提高哈希冲突率,所以我们想要增加元素并且降低冲突率就得增加散列表的长度

image.png

我们从源码中可以看到,DEFAULT_LOAD_FACTOR是源码默认的负载因子最大值为0.75f,所以我们在模拟创建中也以这个指标去扩展数组的长度 。

image.png

2.2、添加节点


这里代码如下:grow代码在下一个

public void put(int key,int val) {
    int index = key%array.length-1;
    Node cur = array[index];
    while (cur!= null) {
        if (cur.key == key) {
            cur.val = val;
            return;
        }
    }
    Node node = new Node(key,val);
    node.next = array[index];
    array[index] = node;
    usedsize++;
    if (loadFactor() >= DEFAULT_LOAD_FACTOR) {
        grow();
    }
}


2.3、扩容(降低哈希冲突)


这里需要先提前标记下cur的下一个节点,不可以使用cur = cur.next ;因为遍历的cur.next会先把新位置链表的头节点接在cur的后面。

我们默认数组扩容为2倍扩容,并且遍历旧哈希表每一个节点放在新对应的散列地址处,因为数组扩容到了2倍会造成 index = x % array.length()-1 的散列地址改变。

private void grow() {
    Node[] newArray = new Node[array.length*2];
    for (int i = 0; i < array.length; i++) {
        Node cur =array[i];
        while (cur != null) {
            int index = cur.key% newArray.length-1;
            Node next = cur.next;
            cur.next = newArray[index];
            newArray[index] = cur;
            cur = cur.next;
        }
    }
    this.array = newArray;
}


2.4、获取key


通过遍历哈希表来找到对应的节点,如果不存在节点返回-1。

public int get(int key) {
    int index = key % array.length-1;
    Node cur = array[index];
    while (cur != null) {
        if (cur.key == key) {
            return cur.val;
        }
    }
    return -1;
}


2.5、负载因子判断


public float loadFactor() {
    return usedsize*1.0f / array.length;
}

完整代码放在Gitee: [HashBuck · 6442b0c · 404NOt/Repository-1 - Gitee.com]

相关文章
|
机器学习/深度学习 自然语言处理 分布式计算
大规模语言模型与生成模型:技术原理、架构与应用
本文深入探讨了大规模语言模型(LLMs)和生成模型的技术原理、经典架构及应用。介绍了LLMs的关键特点,如海量数据训练、深层架构和自监督学习,以及常见模型如GPT、BERT和T5。同时,文章详细解析了生成模型的工作原理,包括自回归模型、自编码器和GANs,并讨论了这些模型在自然语言生成、机器翻译、对话系统和数据增强等领域的应用。最后,文章展望了未来的发展趋势,如模型压缩、跨模态生成和多语言多任务学习。
2251 3
|
11月前
|
SQL 存储 自然语言处理
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
SQL的解析和优化的原理:一条sql 执行过程是什么?
|
存储 SQL 关系型数据库
MySQL高级篇——索引失效的11种情况
索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4
MySQL高级篇——索引失效的11种情况
|
存储 缓存 负载均衡
图解一致性哈希算法,看这一篇就够了!
近段时间一直在总结分布式系统架构常见的算法。前面我们介绍过布隆过滤器算法。接下来介绍一个非常重要、也非常实用的算法:一致性哈希算法。通过介绍一致性哈希算法的原理并给出了一种实现和实际运用的案例,带大家真正理解一致性哈希算法。
29449 66
图解一致性哈希算法,看这一篇就够了!
|
SQL 前端开发 关系型数据库
芋道框架万字详解(前后端分离)、若依框架、yudao-cloud保姆级攻略
芋道框架万字详解(前后端分离)、若依框架、yudao-cloud保姆级攻略
23174 7
|
存储 缓存 JSON
详解HTTP四种请求:POST、GET、DELETE、PUT
【4月更文挑战第3天】
75234 5
详解HTTP四种请求:POST、GET、DELETE、PUT
|
SQL 关系型数据库 MySQL
图解 SQL 里的各种 JOIN
用文氏图表示 SQL 里的各种 JOIN,一下子就理解了。
794 2
c++中的using namespace std;
c++中的using namespace std;
586 1
|
网络协议 安全 网络安全
ARP协议详解及其工作原理
【8月更文挑战第31天】
1589 0
|
监控 Linux
Linux的epoll用法与数据结构data、event
Linux的epoll用法与数据结构data、event
336 0

热门文章

最新文章

下一篇
开通oss服务