SR 哈希表

131 阅读4分钟

昨天我们浅浅介绍了一下哈希表的基本结构以及优劣,今天来主要介绍一下哈希表的实现部分

哈希表的原理及实现

哈希函数

哈希函数是将任意长度的消息压缩到某一固定长度的函数。在哈希表中,哈希函数的作用是将键映射到数组的某个位置上,以便后续的操作可以快速进行。常见的哈希函数有以下几种: 直接寻址法

直接寻址法是最简单的哈希函数,它将键的每一位数字依次乘以一个常数(称为散列值),然后将这些乘积相加,最后对结果取模,就可以得到对应的数组下标。这种方法的优点是实现简单,缺点是冲突概率较高。 除留余数法

除留余数法也是一种常见的哈希函数,它是将键的一个位数或几位二进制数作为关键字,然后将关键字拆分成若干个子串,每个子串对应数组的一个位置。接着,对每个子串进行哈希运算,得到一些余数,再将这些余数分配到数组的不同位置上。这种方法的优点是冲突概率较低,缺点是需要更多的空间来存储子串和余数。 平方取中法

平方取中法是一种比较常用的哈希函数,它是将键的每一位数字平方后取中间几位,然后将这些数字作为关键字,同样拆分成若干个子串并进行哈希运算。最后,将得到的余数分配到数组的不同位置上。这种方法的优点是冲突概率较低,缺点是需要更多的空间来存储子串和余数。 拉链法解决冲突

由于哈希函数可能会产生冲突,即不同的键被映射到了同一个位置上。为了解决这个问题,哈希表通常采用拉链法(又称开放地址法)。当发生冲突时,不再使用原来的键值对,而是在数组中找到第一个空闲位置,并将新的键值对插入到这个位置上。这样,当再次需要查找原来的键时,就需要进行一定的变换才能找到正确的位置。 线性探测法解决线性探测问题

线性探测法是解决哈希表线性探测问题的一种常用方法。它的基本思想是:对于一个元素 e (key),如果 e 在 table[0...table.length-1] 中的任何一个位置上出现过,那么就返回该位置;否则就在 table 的末尾添加一个元素 e,并返回其索引 i。这里的关键是如何判断 e 是否在 table 中出现过。一种简单的方法是使用两个指针 i 和 j,分别指向 table[0] 和 table.length-1。

哈希表的实现方式有很多种,常见的有数组实现、链式实现和红黑树实现等。其中,数组实现是最简单的一种,也是应用最广泛的。在数组实现中,我们通常会将哈希表的大小设置为一个质数,这样可以使得哈希冲突的概率最小化。同时,为了解决哈希冲突,我们还需要使用开放地址法或链式法来处理冲突。


import java.util.HashMap;

public class HashTable {
    private static final int HASH_SIZE = 100; // 哈希表大小
    private static final String[] KEY_VALUE_ARRAY = {"key1", "value1", "key2", "value2", "key3", "value3"}; // 键值对数组
    
    private HashMap<String, String> hashMap; // 哈希表
    
    public HashTable() {
        this.hashMap = new HashMap<>(HASH_SIZE); // 初始化哈希表为空
    }
    
    // 添加键值对
    public void put(String key, String value) {
        hashMap.put(key, value); // 直接将键值对添加到哈希表中
    }
    
    // 根据键获取值
    public String get(String key) {
        return hashMap.get(key); // 在哈希表中查找键对应的值并返回
    }
    
    public static void main(String[] args) {
        HashTable hashTable = new HashTable();
        hashTable.put("key1", "value1");
        hashTable.put("key2", "value2");
        hashTable.put("key3", "value3");
        
        System.out.println(hashTable.get("key1")); // 应该输出 "value1"
        System.out.println(hashTable.get("key2")); // 应该输出 "value2"
        System.out.println(hashTable.get("key4")); // 应该输出 null,因为键"key4"不在哈希表中
    }
}

这个哈希表类使用了Java中的HashMap类来实现哈希表。put()方法直接将键值对添加到哈希表中,get()方法在哈希表中查找键对应的值并返回。在main()方法中,我们创建了一个HashTable对象,并向其中添加了三个键值对。然后分别调用put()和get()方法来测试哈希表的功能。

总结

这下哈希表的介绍就告一段落了。