JAVA-数据结构

1. 哈希表

哈希表本质就是一个数组,每一个元素都有key和value以及hash值,hash值是由每个元素的key计算得来的,

计算公式为:hash = 元素key % 数组长度

但是求模(%)的效率很低,所以我们可以用与(&)来进行替代

替换后的计算公式:hash = 元素key & (数组长度 - 1)

接下来是一个hash表的基本代码实现:

HashTable

/**
 * 为了让超出数组长度的hash可以存入,我们可以使用求模来计算对应的索引位置,但是求模性能不好,
 * 如果数组长度是 2的n次方,我们可以把求模(%)替换成 按位与(&)(数组长度 - 1)
 */
public class HashTable {
    static class Entry {
        int hash;
        Object key;
        Object value;
        Entry next;

        public Entry(int hash, Object key, Object value) {
            this.hash = hash;
            this.key = key;
            this.value = value;
        }
    }

    Entry[] table = new Entry[16];
    int size = 0;

    // 根据 hash 码获取 value
    Object get(int hash, Object key) {
        int index = hash & (table.length - 1);
        if (table[index] == null) {
            return null;
        }
        Entry p = table[index];
        while (p != null) {
            if (p.key.equals(key)) {
                return p.value;
            }
            p = p.next;
        }
        return null;
    }

    // 向 hash 表中存入新 key value, 如果 key 重复,则更新 value
    void put(int hash, Object key, Object value) {
        int idx = hash & (table.length - 1);
        if (table[idx] == null) {
            table[idx] = new Entry(hash, key, value);
        } else {
            Entry p = table[idx];
            while (true) {
                if (p.key.equals(key)) {
                    p.value = value;
                    return;
                }
                if (p.next == null) {
                    break;
                }
                p = p.next;
            }
            p.next = new Entry(hash, key, value);
        }
        size++;
    }

    // 根据 hash 码删除,返回删除的 value
    Object remove(int hash, Object key) {
        int idx = hash & (table.length - 1);
        if (table[idx] == null) {
            return null;
        }
        Entry p = table[idx];
        Entry prev = null;
        while (p != null) {
            if (p.key.equals(key)) {
                // 找到了删除(单向链表删除)
                if (prev == null) {   // 如果要删除的是第一个
                    table[idx] = p.next;
                } else {
                    prev.next = p.next;
                }
                size--;
                return p.value;
            }
            prev = p;
            p = p.next;
        }
        return null;
    }
}

posted @ 2024-11-01 10:54  普信小林  阅读(16)  评论(0)    收藏  举报