哈希表(Hash Table)

二分搜索中提到了在有序集合中查询某个特定元素的时候,通过折半的方式进行搜索是一种很高效的算法。那能否根据特征直接定位元素,而非折半去查找?哈希表(Hash Table),也称为散列表,就是一种数据结构,用于实现键-值对的映射关系。它通过将键映射到特定的值(哈希值)来实现快速的数据检索。

	// Java 中Hash表JDK中有提供两种结构Hashtable、HashMap,使用接口上区别不大
// Hashtable 是Dictionary类的子类,而 HashMap 是AbstractMap类的子类。
// 由于 Dictionary类已经被废弃,因此Hashtable也不再推荐使用。
// 在工程应用上值得注意的是 Hashtable是线程安全的,而HashMap不是 public HashMap<Integer,Long> records1 = new HashMap<>();
public Hashtable<Integer,Long> records2 = new Hashtable<>();

一般而言,哈希表基于哈希函数将键转换为哈希码,然后使用这个哈希码作为索引获取相应的元素。哈希表的优点是具有快速的平均查找时间,通常为O(1)。然而,它也具有一些挑战,如处理哈希冲突、设计良好的哈希函数和维护适当的装载因子。装载因子表示哈希表已用空间与总空间的比例,需要适时进行动态调整以保持哈希表的性能。

	// 示例java中初始化 HashMap的容量以及装载因子。
Map<Integer,Integer> sumMap = new HashMap<>(2000,0.75f);

哈希表在计算机科学中有广泛的应用,包括实现关联数组、数据库索引、缓存、编程语言中的字典和集合等等。

基本概念

哈希函数(Hash Function): 哈希表使用哈希函数来将键转换为整数,通常是数组的索引。哈希函数应该是确定性的,即对于相同的键,它应该生成相同的哈希码。理想情况下,不同的键应该映射到不同的哈希码,但由于哈希函数的有限性,可能会出现哈希冲突。

哈希冲突(Hash Collision): 当两个不同的键映射到相同的哈希码时,发生哈希冲突。哈希表需要处理哈希冲突,以确保不同的键可以正确存储和检索。

存储结构: 哈希表通常由一个数组和一个哈希函数组成。数组的每个元素称为桶(Bucket),它可以存储一个或多个键-值对。

PS:Java 中由于都已经封装好了 HashMap,一般使用可能感知不到这些概念,但要熟练掌握还是需要理解这些基本理念。

基本操作

插入(Insertion): 将键-值对插入哈希表时,首先通过哈希函数计算键的哈希码,然后确定存储位置(桶)。如果存在哈希冲突,通常会使用链表、数组或其他数据结构来解决冲突,并将键-值对添加到存储位置。

查找(Lookup): 查找键对应的值时,使用相同的哈希函数计算哈希码,并在存储位置中查找该键。如果存在哈希冲突,必须在冲突的元素中搜索以找到正确的键-值对。

删除(Deletion): 删除键-值对时,使用相同的哈希函数计算哈希码,然后从存储位置中删除对应的键-值对。

基本应用

Leetcode 383 赎金信【简单】

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

字符可以转换成ASCII数字,数组的下标也是数字。那么利用这种数字映射作为哈希函数,就能够通过字符直接读取数组存储的信息。通过ASCII数组 来记录 magazine 里面包含的各个字符数量,再遍历 ransomNote 使用到的字符判断是否存在于 ASCII数组,并减少数量来标识已经使用过。

借这题不妨讲一讲分块的编码风格。在日常生活中,我们一定有记忆手机号码的经历,一个长长的数字串(比如1234567890)可能很难记忆,但如果将其分成更小的组块,例如(123) 456-7890,就更容易记忆和处理。这个其实在认识心理学里面概念叫:"信息分块"(chunking),_指的是将大量的信息分割成更小的、有意义的单元,以便更容易处理和记忆。_关键点是人类大脑通过将信息分成较小的组块,可以更有效地处理和记忆信息。

所谓代码可读性其实就是对代码的认识,将信息认识心理学的分块理论应用到代码可读性就是提倡的 分块编码。可以将冗余的代码分成一块一块的逻辑,块与块之间用空行来进行视觉上的分块,方便小段小段的去理解代码逻辑;每一块代码可以适当的加上注释以方便阅读。当然这些都是形式上的,更重要的是每一块代码逻辑都会聚焦一个目标,这样写法也有利于编码者自身对逻辑的梳理以及减少bug。

不妨练习下类似问题,参考代码就不附上了,相信一定能够完成。

Leetcode 242. 有效的字母异位词【简单】

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

更多应用

Leetcode 560. 和为 K 的子数组【中等】

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。

子数组是数组中元素的连续非空序列。

Leetcode 3 无重复字符的最长子串【中等】

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

数据结构与算法 | 哈希表(Hash Table)的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. 数据结构 哈希表(Hash Table)_哈希概述

    哈希表支持一种最有效的检索方法:散列. 从根来上说,一个哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素. 哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表.哈希 ...

  3. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  4. python数据结构与算法——哈希表

    哈希表 学习笔记 参考翻译自:<复杂性思考> 及对应的online版本:http://greenteapress.com/complexity/html/thinkcomplexity00 ...

  5. Java数据结构和算法 - 哈希表

    Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...

  6. 什么叫哈希表(Hash Table)

    散列表(也叫哈希表),是根据关键码值直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. - 数据结构 ...

  7. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  8. golang数据结构之散哈希表(Hash)

    hash.go package hash import ( "fmt" ) type Emp struct { ID int Name string Next *Emp } //第 ...

  9. 哈希表(Hash table)

  10. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

随机推荐

  1. 安装mysql5.7.20,和遇到的一些错误及解决方案

    下载: mysql-5.7.20是解压版免安装的,mysql-5.7.20下载地址:http://dev.mysql.com/downloads/mysql/ 2.安装 解压在你喜欢的位置 3.配置 ...

  2. PE文件整体结构解析

    DOS头 在之前,我们已经了解过PE文件的整体结构了,并且我们进行了静动态差异的文件分析,其开头部分就是DOS 部分,包含了DOS MZ文件头和DOS块,那么我们来了解一些DOS部分的结构和其相关意义 ...

  3. Easygraph:全面高效的图分析与社会计算开源工具

    前言图是对事物之间关系的一种原生的表达,利用图可以深入直接地认识世界中的关联.社交网络.交易数据.知识图谱.交通运输.生物技术等都是图数据的典型应用.社交网络是一种特殊的图数据,它建立在图网络的基础上 ...

  4. Flutter系列文章-Flutter进阶

    在前两篇文章中,我们已经了解了Flutter的基础知识,包括Flutter的设计理念.框架结构.Widget系统.基础Widgets以及布局.在本文中,我们将进一步探讨Flutter的高级主题,包括处 ...

  5. 2021-7-7 VUE笔记2

    if实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <scri ...

  6. #Powerbi 1分钟学会利用AI,为powerbi报表进行高端颜色设计

    在BI报表的设计中,配色方案往往成为一大难题,一组切合主题.搭配合理的颜色设计往往能为我们的报表,加分不少. 今天,就介绍一个AI配色的网站,利用AI为pbi报表进行配色设计. 一:网站网址 http ...

  7. React: 按钮点击时修改颜色

    背景 当存在多个点击按钮时,需要提示用户点击的哪个按钮,所以要进行颜色的修改 import * as React from 'react'; import './style.css'; export ...

  8. Vue错误:Cannot read properties of undefined (reading '$router')

    解决方案 这是由于this的指向有问题,我们只需要重新声明一下this就可以重新调用了

  9. markdown之mermaid

    官方文档 01 简单的流程图 TD或TB:top to bottom,从上到下的流程图 LR:从左到右 其它:RL,BT flowchart LR; A([节点A的圆矩框]) --> |AB之间 ...

  10. 简述redis的单线程模式

    前言 在redis版本6之前,网络IO和键值对读写都是由一个线程来完成的.而redis的其他功能,比如持久化.异步删除.集群数据同步等,是由其他线程完成的. 为什么采用单线程 多线程有助于提升吞吐率( ...