简单哈希表
基于数组实现的简单哈希表,使用取模法处理哈希冲突(就是发生冲突时直接替代)

public class HashTable<E> {
    // 哈希表的初始容量,使用质数可减少哈希冲突
    private final int TABLE_SIZE = 10;
    // 使用Object数组存储元素,需进行类型转换
    private final Object[] TABLE = new Object[TABLE_SIZE];

    public void insert(E obj) {
        // 计算元素在数组中的存储位置
        int index = hash(obj);
        // 直接存储元素,冲突时会覆盖原有值
        TABLE[index] = obj;
    }

    public boolean contains(E obj) {
        // 计算元素理论上的存储位置
        int index = hash(obj);
        // 使用引用相等判断元素是否存在(非值相等)
        return TABLE[index] == obj;
    }

    private int hash(E obj) {
        // 获取对象原始哈希码
        int hashCode = obj.hashCode();
        // 取模运算确保索引在数组范围内
        return hashCode % TABLE_SIZE;
    }
}

以下是改进的哈希表:
基于链地址法(拉链法)实现的哈希表。
每个哈希槽位存储一个链表头节点,冲突元素通过链表连接(依次存储在链表当中),这样就可以解决上面发生元素冲突时覆盖的问题了

public class HashTable<E> {
    // 哈希表初始容量
    private final int TABLE_SIZE = 10;
    // 存储链表头节点的数组,使用泛型数组需通过强制类型转换创建
    private final Node<E>[] TABLE = new Node[TABLE_SIZE];

    /**
     * 构造函数初始化哈希表
     * 为每个槽位创建哑元头节点,减少插入删除时的边界判断
     */
    public HashTable() {
        for (int i = 0; i < TABLE_SIZE; i++)
            TABLE[i] = new Node<>(null); // 创建哑元头节点
    }

    public void insert(E obj) {
        int index = hash(obj); // 计算哈希值
        Node<E> head = TABLE[index]; // 获取槽位的头节点
        Node<E> node = new Node<>(obj); // 创建新节点
        // 头插法插入新节点
        node.next = head.next;
        head.next = node;
    }

    public boolean contains(E element) {
        int index = hash(element); // 计算哈希值
        Node<E> node = TABLE[index].next; // 获取第一个有效节点
        // 遍历链表查找元素
        while (node != null) {
            if (node.element == element) // 使用引用相等判断
                return true;
            node = node.next;
        }
        return false;
    }

    /**
     * 返回哈希表的字符串表示形式
     * 格式:每个槽位的链表元素用"->"连接,槽位间用换行分隔
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < TABLE_SIZE; i++) {
            Node<E> head = TABLE[i].next; // 获取第一个有效节点
            while (head != null) {
                builder.append(head.element).append("->");
                head = head.next;
            }
            builder.append("\n"); // 槽位结束添加换行
        }
        return builder.toString();
    }

    private int hash(E obj) {
        int hashCode = obj.hashCode();
        return hashCode % TABLE_SIZE; // 取模运算确保索引合法
    }

    /**
     * 链表节点类,存储元素和指向下一个节点的引用
     */
    private static class Node<E> {
        private final E element; // 节点存储的元素
        private Node<E> next; // 指向下一个节点的引用

        public Node(E element) {
            this.element = element;
        }
    }
}
分类: 数据结构 标签: 哈希表

评论

暂无评论数据

暂无评论数据

目录