Java深入了解数据结构之哈希表篇

Java深入了解数据结构之哈希表篇

1. 哈希表的定义

哈希表(Hash Table),也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数(Hash Function)。

哈希表是基于哈希函数实现的,哈希函数将关键字映射到哈希表中的位置,如果存在两个关键字映射到同一个位置,则发生碰撞。

2. 哈希表的工作原理

哈希表的工作原理可以分为以下几个步骤:

  1. 建立哈希表。
  2. 根据哈希函数把关键字映射到表的位置。
  3. 如果该位置已经有其他关键字占用,则发生碰撞。
  4. 碰撞解决(拉链法,开放地址法等)。
  5. 查找记录:根据关键字计算哈希值,找到对应的数据。

3. 哈希表的特点

哈希表的特点:

  1. 查找/插入/删除的时间复杂度都是O(1)的。
  2. 哈希表大小一般为素数,可以有效避免哈希冲突。
  3. 哈希表的哈希函数应该尽量少的发生哈希冲突。

4. 哈希表的实现

哈希表的实现有多种方法,比如:

  1. 拉链法
  2. 线性探测法
  3. 双散列法

4.1 拉链法

拉链法是哈希表实现最为常用也最为简单的方法。拉链法把每个哈希值相同的元素都放到一个链表中,查询时遍历该链表,查找对应元素。

public class HashTable<T> {

    private int size;
    private LinkedList<T>[] table;

    public HashTable() {
        size = 17;
        table = new LinkedList[size];
    }

    public void put(T element) {
        int hash = element.hashCode() % size;
        if (table[hash] == null) {
            table[hash] = new LinkedList<>();
        }
        table[hash].add(element);
    }

    public T get(T element) {
        int hash = element.hashCode() % size;
        LinkedList<T> list = table[hash];
        if (list != null) {
            for (T e : list) {
                if (e.equals(element)) {
                    return e;
                }
            }
        }
        return null;
    }
}

4.2 线性探测法

线性探测法是一种开放地址法,也就是说,发生哈希冲突时,根据一定规则继续探测下一个位置,直到找到空位置或者查询结束为止。

public class LinearHashTable<T> {

    private int size;
    private Object[] table;

    public LinearHashTable() {
        size = 17;
        table = new Object[size];
    }

    public void put(T element) {
        int hash = element.hashCode() % size;
        while (table[hash] != null) {
            hash = (hash + 1) % size;
        }
        table[hash] = element;
    }

    public T get(T element) {
        int hash = element.hashCode() % size;
        while (table[hash] != null && !table[hash].equals(element)) {
            hash = (hash + 1) % size;
        }
        if (table[hash] != null) {
            return (T) table[hash];
        }
        return null;
    }
}

5. 示例说明

5.1 示例一

一种常见的使用哈希表的场景是在数据去重上。比如,去掉一个文件中的重复单词,可以使用哈希表来实现。

public static void main(String[] args) {
    try (Scanner scanner = new Scanner(new File("input.txt"), "UTF-8");
         PrintWriter writer = new PrintWriter("output.txt", "UTF-8")) {
        Set<String> set = new HashSet<>();
        while (scanner.hasNext()) {
            String word = scanner.next();
            if (!set.contains(word)) {
                set.add(word);
                writer.print(word + " ");
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

5.2 示例二

哈希表还广泛应用于快速查找。比如,在一堆卡片中查找编号为123456的卡片,可以使用哈希表来实现。

public static void main(String[] args) {
    Map<String, Card> map = new HashMap<>();
    List<Card> cards = new ArrayList<>();
    cards.add(new Card("123456", "xxx"));
    cards.add(new Card("654321", "yyy"));
    cards.add(new Card("111111", "zzz"));
    for (Card card : cards) {
        map.put(card.getId(), card);
    }
    Card target = map.get("123456");
    System.out.println(target.getName());
}
class Card {
    private String id;
    private String name;
    public Card(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public String getName() {
        return name;
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java深入了解数据结构之哈希表篇 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 李航统计学习概述

    监督学习 感知机 概念: 感知机模型的基本形式是: \(f(x) = sign(w \cdot x + b)\) 其中,\(x\) 是输入样本的特征向量,\(w\) 是权值向量,\(b\) 是偏置量,\(w \cdot x\) 表示向量 \(w\) 和 \(x\) 的点积。\(sign\) 函数表示符号函数,当输入大于 0 时输出 1,否则输出 -1。 要求…

    算法与数据结构 2023年4月25日
    00
  • C语言数据结构之图书借阅系统

    C语言数据结构之图书借阅系统是一款基于C语言的软件,主要用于管理图书馆的借阅信息,并提供图书查询、借阅、归还等功能。本文将介绍图书借阅系统的完整攻略。 设计思路 图书借阅系统的设计主要包括三个阶段:系统设计、数据结构设计和用户接口设计。 系统设计 系统设计是构建整个系统的重要阶段,需要确定系统的功能需求、模块划分和流程控制。本系统的主要功能包括: 图书查询:…

    数据结构 2023年5月17日
    00
  • 「学习笔记」AC 自动机

    「学习笔记」AC 自动机 点击查看目录 目录 「学习笔记」AC 自动机 算法 问题 思路 代码 例题 Keywords Search 玄武密码 单词 病毒 最短母串 文本生成器 背单词 密码 禁忌 前置:「学习笔记」字符串基础:Hash,KMP与Trie。 好像对例题的讲解越来越抽象了? 算法 问题 求 \(n\) 个单词在一个长度为 \(m\) 的文章里出…

    算法与数据结构 2023年5月5日
    00
  • 回溯理论基础及leetcode例题

    学习参考 回溯 与递归相辅相成;回溯是递归的副产品,只要有递归就会有回溯。回溯函数也就是递归函数,指的都是一个函数。 回溯搜索法 纯暴力搜索解决的问题 组合问题:N个数里面按一定规则找出k个数的集合切割问题:一个字符串按一定规则有几种切割方式子集问题:一个N个数的集合里有多少符合条件的子集排列问题:N个数按一定规则全排列,有几种排列方式(与组合差别,排列有元…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构之单链表的查找和建立

    C语言数据结构之单链表的查找和建立 什么是单链表? 单链表是一种常见的数据结构,是由若干个节点(Node)组成的链式结构,每个节点存储着链表中的元素和指向下一个节点的指针。 单链表的优点是插入、删除元素简单,但是查找元素比较困难。 在C语言中,我们可以使用结构体来定义一个节点: struct ListNode { int val; struct ListNo…

    数据结构 2023年5月17日
    00
  • C++数据结构哈希表详解

    C++数据结构哈希表详解 哈希表(Hash Table)是一种非常重要的数据结构,用于实现字典等各种应用。哈希表将关键字映射到一个固定大小的数据集合中,以支持常数时间复杂度的插入、查找和删除操作。哈希表的核心思想是将关键字通过哈希函数(Hash Function)映射到数据集合中的一个索引位置,哈希函数需要满足良好的散列性质,使得关键字能够均匀地散布在数据集…

    数据结构 2023年5月17日
    00
  • Java数据结构之循环队列简单定义与用法示例

    Java数据结构之循环队列简单定义与用法示例 什么是循环队列? 循环队列是一种数据结构,它具有先进先出(FIFO)的特点,即最先进队列的元素总是被最先取出。不同于普通队列,循环队列的尾指针指向数组的头部,因此可以实现循环利用数组空间,提高存储空间的利用率,避免因队列的操作大量移动数组元素而导致的时间浪费。 循环队列的基本操作 循环队列的基本操作包括:入队、出…

    数据结构 2023年5月17日
    00
  • C++ 数据结构二叉树(前序/中序/后序递归、非递归遍历)

    下面是关于C++二叉树数据结构的详细攻略。 什么是二叉树 二叉树是一种树形数据结构,每个节点最多有两个子节点:左节点和右节点。一个节点没有左节点或右节点则分别为左子树和右子树为空。 递归遍历二叉树 前序遍历 前序遍历是指对于一棵二叉树,在访问右子树之前,先访问根节点,然后访问左子树。 下面是C++递归遍历二叉树的前序遍历示例代码: template <…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部