哈希桶(详解&创建)

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

一、什么是哈希桶?


       开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址(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]

相关文章
|
23天前
|
存储 算法 C++
【C++】哈希桶
哈希桶是哈希表中的基本存储单元,用于存放通过哈希函数映射后的数据元素。当不同元素映射至同一桶时,产生哈希冲突,常用拉链法或开放寻址法解决。哈希桶支持高效的数据插入、删除与查找操作,时间复杂度通常为O(1),但在最坏情况下可退化为O(n)。
38 6
|
2月前
|
存储 索引 Python
什么是可哈希对象,它的哈希值是怎么计算的?
什么是可哈希对象,它的哈希值是怎么计算的?
86 6
|
6月前
|
存储
开散列哈希桶
开散列哈希桶
|
6月前
|
存储 C++ 容器
c++实现哈希桶
这篇文章回顾了闭散列的概念,指出在数据冲突时,闭散列会自动寻找后续未占用的位置插入数据。然而,这种方法可能导致某些元素状态变为删除,从而在查找时产生问题。为了解决这个问题,文章介绍了拉链法(哈希桶)作为改进策略。拉链法在每个哈希表位置上维护一个链表,冲突的数据挂载在相应位置的链表上。文章详细描述了拉链法的插入、查找和删除操作,并提供了相关代码示例。在插入过程中,当负载因子达到1时,哈希表会进行扩容,同时避免了频繁创建和销毁节点,提高了效率。最后,文章通过测试代码展示了拉链法的正确性。
|
7月前
|
存储 Serverless C++
【C++高阶(五)】哈希思想--哈希表&哈希桶
【C++高阶(五)】哈希思想--哈希表&哈希桶
|
存储 算法 Shell
哈希表、哈希桶(C++实现)【STL】
哈希表、哈希桶(C++实现)【STL】
196 0
|
存储 缓存 算法
一篇文章让你学会什么是哈希(上)
哈希概念 哈希在C++中有广泛的应用,它是一种用于快速查找和存储数据的数据结构和算法。以下是一些常见的哈希在C++中的应用: 哈希表(Hash Table):哈希表是一种高效的数据结构,用于存储键值对。在C++中,std::unordered_map 和 std::unordered_set 是标准库提供的哈希表实现。
|
7月前
|
存储 Serverless
哈希及哈希表的实现
哈希及哈希表的实现
64 0
|
7月前
|
存储 Serverless 测试技术
C++【初识哈希】
C++【初识哈希】
65 0