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

yizhihongxing

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日

相关文章

  • C语言数据结构之二叉树详解

    C语言数据结构之二叉树详解 什么是二叉树? 二叉树是一种非常常用的数据结构,它具有以下几个特点: 在二叉树中,每个节点最多有两个子节点,其中一个称为左子节点,另一个称为右子节点。 每个节点都有一个值,这个值可以是任意类型的,比如整数、字符、指针等等。 可以使用递归的方式来遍历一个二叉树,具体包括前序遍历、中序遍历和后序遍历。 二叉树的存储方式 二叉树可以使用…

    数据结构 2023年5月17日
    00
  • 详解C语言实现空间索引四叉树

    详解C语言实现空间索引四叉树攻略 四叉树是一种常见的空间索引方法,可以有效地处理二维或三维空间中的数据。本攻略将详细介绍使用C语言实现空间索引四叉树的方法,包括数据结构的设计,插入和查询操作的实现。 数据结构设计 结点结构体 struct QuadtreeNode { int depth; // 结点深度 double x, y; // 结点中心坐标 dou…

    数据结构 2023年5月17日
    00
  • Mysql 数据库结构及索引类型

    好的。首先,我们需要了解 Mysql 数据库的基本结构和索引类型。 Mysql 数据库结构 Mysql 数据库包含多个数据库,每个数据库包含多个数据表,每个数据表包含多个数据记录(或者叫行)。关键的概念包括数据库、数据表、数据记录以及 Mysql 列类型等。 数据库 Mysql 数据库是一个命名的容器,用于存储和管理相关数据表。可以使用以下 SQL 代码来创…

    数据结构 2023年5月17日
    00
  • c语言 数据结构实现之字符串

    下面是详细讲解“c语言 数据结构实现之字符串”的完整攻略。 1. 什么是字符串? 字符串是由一组字符组成的序列,字符可以是字母、数字、标点符号等,字符串常用于文本处理。 在C语言中,字符串是以‘\0’ 结束的字符数组。 2. 字符串的常见操作 常见的字符串操作包括:复制、比较、连接、查找等。 2.1 字符串复制 字符串复制是将一个字符串的内容复制到另一个字符…

    数据结构 2023年5月17日
    00
  • C语言数据结构之图书借阅系统

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

    数据结构 2023年5月17日
    00
  • C语言数据结构与算法之图的遍历(一)

    我来给您详细讲解一下“C语言数据结构与算法之图的遍历(一)”的完整攻略。 简介 本篇攻略主要介绍了图的遍历问题。图是由若干个点和连接这些点的边构成的数据结构,常用来表示复杂的关系和网络。图的遍历就是从图的某一点开始,按照一定的规则沿着边逐个访问图中所有的点,不重不漏地遍历整个图。 在本篇攻略中,我们将探讨图的深度优先遍历(DFS)和广度优先遍历(BFS)两种…

    数据结构 2023年5月17日
    00
  • Java数据结构之链表的概念及结构

    Java数据结构之链表的概念及结构 链表的概念 链表是一种非顺序存储的容器,它由一个个结点组成,每个结点包含两部分,数据域和指针域。数据域是存储数据的部分,指针域是指向下一个结点的位置。 相比于数组,链表插入和删除操作的时间复杂度更低,但是访问元素时需要遍历整个链表,时间复杂度相对较高。 链表的结构 链表结构包含两个重要的部分:结点和链表。 结点(Node)…

    数据结构 2023年5月16日
    00
  • Unity接入高德开放API实现IP定位

    Unity接入高德开放API实现IP定位攻略 本文将详细介绍如何在Unity中接入高德开放API实现IP定位功能。 准备工作 在开始之前,需要准备以下内容: 高德开放平台账号 Unity集成开发环境 一台联网的电脑或手机 开始集成 1. 创建Unity项目 首先,我们需要在Unity中创建一个新的项目。 2. 导入AMap3D SDK 将下载好的AMap3D…

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