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日

相关文章

  • 数据结构之堆详解

    数据结构之堆详解 什么是堆? 堆(Heap)是一种特殊的树形数据结构。堆具有以下两个特点: 堆是一颗完全二叉树; 堆中每个节点的值都必须大于等于或小于等于其左右子节点的值,分别称作大根堆和小根堆。 上述的大根堆和小根堆其实是两种不同的堆的实现方式。对于大根堆,每个节点的值都比其左右子节点的值要大;小根堆则相反,每个节点的值都比其左右子节点的值要小。 堆的基本…

    数据结构 2023年5月17日
    00
  • Java常见数据结构面试题(带答案)

    Java常见数据结构面试题(带答案)完整攻略 介绍 在Java面试中,数据结构不可避免地成为一部分的考察内容。因此,掌握Java常见数据结构,对于提高面试成功率十分必要。本篇攻略将会介绍常见的Java数据结构,并提供相应的面试题目和答案,希望可以帮助面试者在面试当中更好地展示自己的实力。 目录 结构体 数组 链表 栈 队列 树 哈希表 结构体 在Java中并…

    数据结构 2023年5月17日
    00
  • C语言线性表的顺序表示与实现实例详解

    C语言线性表的顺序表示与实现实例详解 1. 线性表的定义 线性表是一种线性结构,它是由n个数据元素(n≥0)组成的有限序列。当n=0时,我们称为一个空表。 在C语言中,我们可以通过数组来实现线性表的顺序表示,每个数据元素都存在数组的一个位置中,数组下标可以看作是该数据元素的位置。 2. 线性表的基本操作 一个线性表的基本操作有以下几种: 2.1 初始化线性表…

    数据结构 2023年5月17日
    00
  • Go select使用与底层原理讲解

    标题:Go select使用与底层原理讲解 标准库提供的go语言引擎的选择器select语法是并发编程中常用的语法之一,它允许协程同时等待多个IO操作的完成,通常会和通道配合使用。在本文中,我们将详细讲解Go select的使用和底层原理。 Go select的使用 基本语法 在Go语言中,select语法的基本语法如下: select { case &lt…

    数据结构 2023年5月17日
    00
  • Java数据结构二叉树难点解析

    Java数据结构二叉树难点解析 什么是二叉树 二叉树是一种非常常见的数据结构,它具有以下特点: 每个节点都最多有两个子节点。 左子节点的值小于等于父节点的值,右子节点的值大于等于父节点的值。 二叉树可以用递归的方式实现,如下所示: class TreeNode { int val; TreeNode left; TreeNode right; TreeNod…

    数据结构 2023年5月17日
    00
  • C语言数据结构之平衡二叉树(AVL树)实现方法示例

    C语言数据结构之平衡二叉树(AVL树)实现方法示例 介绍 AVL树是一种自平衡二叉搜索树,它保证了所有节点的左右子树高度差不超过1,从而提高了查找、插入和删除操作的效率。本篇文章将介绍如何使用C语言实现AVL树,并提供两个例子以说明实现方法。 实现方法 结构体定义 首先,定义AVL树节点的结构体,包括该节点存储的值、该节点的高度、该节点的左右子树指针。 ty…

    数据结构 2023年5月17日
    00
  • Java数据结构之HashMap和HashSet

    Java数据结构之HashMap和HashSet HashMap 介绍 HashMap是一种基于哈希表实现的Map集合,它提供了快速的插入、查询、删除操作。HashMap中存储的元素是以键值对(Key-Value)的形式存储的,其中Key是用来从Map中查找值的索引,Value是存储在Map中的值。HashMap中的Key和Value都可以为null,但是在…

    数据结构 2023年5月17日
    00
  • 浅谈Java数据结构之稀疏数组知识总结

    浅谈Java数据结构之稀疏数组知识总结 稀疏数组的定义 稀疏数组是指当一个数组中大部分元素是相同的值时,可以使用稀疏数组来保存该数组。稀疏数组的必要性在于节省内存空间,当数组中元素过多时,存储数组所需的内存空间也呈指数级增长。 稀疏数组的特点 稀疏数组存储的是一个原始的二维数组。 稀疏数组的第一行保存原始数组的基本信息,包括行数、列数、有效值的个数。 稀疏数…

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