数据结构 - 散列表,初探

news2024/11/23 8:47:50

今天我们继续学习新的数据结构-散列表。

在这里插入图片描述

01定义

我们先来了解一些常见概念名词解释。

散列:散列表的实现叫做散列,是一种实现以常数级时间复杂度执行查找、插入和删除的技术;

散列值:通过散列函数对输入值(key)计算出来的结果,用来表示key的唯一性,它通常是一个长度固定的值,即无论key多大,散列值的长度都是固定的;

散列地址:通过散列值计算出来的存储位置,即存储value的位置,通常使用散列值和散列表的大小取模得到散列地址。

碰撞:也叫冲突,指两个不同的key,经过散列函数计算后得到相同的散列值;

负载系数:也叫负载因子,用来衡量散列表填充程度,通过散列表已存储的元素个数除以散列表的大小计算可得;

散列函数:也叫哈希函数,指将key映射为散列值的函数;

散列表又称哈希表,是以「key-value」形式存储数据的数据结构。可以理解为任意的key都可以唯一对应到内存中的某个地址,而这个地址就存放着value,通过key快速查找到value。也可以把散列表理解为一种高级的数组,其中key就相当于数组下标,此数组下标不但可以是整数,还可以是浮点数、字符串、结构体等,其中value就相当于数组元素值。

通过前面的数据结构学习,我们知道数组是查找容易、插入和删除困难;链表是查找困难、插入和删除容易;而散列表是集两者之大成,做大查找、插入、删除都容易的一种数据结构。

本质上来说散列表就是一个数组。虽然上面把key比作数组下标,但是key并不真的是数组下标。因此这中间就需要一个转换工具把key转换为数组下标,而这个工具就是散列函数。

如下图,展示了在散列表中如何通用key获取到value的过程。输入key4通过散列函数计算得到数组索引3,最后通过数组下标取出value4。

在这里插入图片描述

02散列函数

散列技术核心难点之一就是如何设计一个准确、快速、均匀、抗碰撞的散列函数。而一个好的散列函数对散列表是至关重要的,这影响散列表的存储和检索效率。

在这里插入图片描述

1、四大特性

(1)确定性:指相同的输入key总能输出相同的结果;

(2)快速计算:指计算散列值的速度尽可能的快;

(3)均匀分布:指尽量将输入key均匀的映射到散列表中,以减少碰撞;

(4)抗碰撞性:指尽量减少不同的输入key生成出相同的散列值概率;

2、常见散列函数算法

(1)取模算法

该算法是一种最简单且常用的散列函数构造方法。

原理:通过将key取模散列表的大小(通常是质数)来计算散列值;

公式:hash(key) = key % m;

优点:简单易实现,计算速度快;

缺点:如果m不是质数,会增加碰撞概率,因此m最好选用质数来减少碰撞概率。

示例:假设我们有个散列表,大小为10,分别散列以下key:11,23,4,19

hash(11) = 11 % 10 = 1

hash(23) = 23 % 10 = 3

hash(4) = 4 % 10 = 4

hash(17) = 17 % 10 = 7

则最终生成的散列值分别为1、3、4、7,而这些值就可以作为散列表的索引。

(2)乘法算法

该算法是通过乘法来降低碰撞概率,以使散列值均匀分布;

原理:通过将key与一个固定常数 A(通常是黄金比例的倒数)相乘,取其乘积的小数部分,再乘以散列表的大小(通常是质数),所得结果的整数部分即为散列值;

公式:hash(key) = ⌊m * (key * A % 1)⌋;

优点:简单易实现,散列值分布更均匀;

缺点:常数A的选择对计算结果散列值影响很大,选择不好很容易增加碰撞概率;

示例:假设我们有个散列表,大小为10,常数A为0.618,分别散列以下key:11,23,4,19

hash(11) = ⌊10 * (11 * 0.618 % 1)⌋ = 7

hash(23) = ⌊10 * (23 * 0.618 % 1)⌋ = 2

hash(4) = ⌊10 * (4 * 0.618 % 1)⌋ = 4

hash(17) = ⌊10 * (17 * 0.618 % 1)⌋ = 5

则最终生成的散列值分别为7、2、4、5,而这些值就可以作为散列表的索引。

(3)DJB2算法

DJB2 是一种使用广泛的字符串散列算法,它简单而高效,由 Daniel和J. Bernstein 提出。其核心公式:hash = hash * 33 + c,其中 33 是常用的基数。

原理:使用一个初始散列值(通常是5381),然后通过对key的每一个字符的ASCII值进行逐步加权处理,最终得到散列值;

公式:hash(key) = {

hash = 5381

for character c in string:

hash = ((hash << 5) + hash) + c

return hash & 0xFFFFFFFF

}

优点:简单易懂,速度快,底碰撞;

缺点:基数(33)的选择对散列性能有一定影响,虽然普遍表现良好,但并不是最佳选择;散列值的输出通常需要进行掩码操作(如 & 0xFFFFFFFF),这可能导致部分信息丢失,尤其在处理较大数据时。

上面的公式中没有使用hash * 33 + c,而是使用((hash << 5) + hash) + c是因为位运算效率更高。

(4)其他算法

除了以上三种算法还有很多其他算法,比如和DJB2算法类似的BKDR算法、PJW算法,比如还有诸如:直接定算法、数字分析算法、平方取中算法、折叠算法、随机数算法等等,这里就不一一细说了,有兴趣的可以自己研究研究。

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2224452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c++篇】:从基础到实践--c++内存管理技巧与模版编程基础

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 前言一.c/c内存分布二.c/c的动态内存管理方式2.1.c语言的动态内存管…

JavaEE初阶---多线程(五)---定时器/线程池介绍

文章目录 1.定时器的介绍2.线程池2.1为什么需要使用线程池2.2如何进行线程池的创建2.3普通的构造方法的局限性2.4该种对象创建的方法的特点2.5线程池的模拟实现的逻辑 3.ThreadPoolExecutor类的介绍3.1构造方法3.2四种拒绝的策略 1.定时器的介绍 下面的这个就是我们的这个定时…

基于JSP的高校食堂食材选购管理系统【附源码】

基于JSP的高校食堂食材选购管理系统 效果如下&#xff1a; 系统首页界面 用户登录页面 食材信息页面 论坛交流界面 管理员登录界面 管理员功能主界面 食材信息管理界面 订单配送管理界面 用户功能主界面 商家功能主界面 司机功能主界面 研究背景 近年来互联网技术的发展使得…

【C++篇】手撕string类:从初级到高级入门

1.为什么手撕string类 在面试或者一些学习场景中&#xff0c;手撕 string 类不仅仅是对字符串操作的考察&#xff0c;更多的是考察程序员对 C 内存管理的理解。例如&#xff0c;深拷贝与浅拷贝的实现&#xff0c;如何正确重载赋值运算符&#xff0c;如何避免内存泄漏&#xff…

线上环境的 JAVA 程序占用太多 CPU 资源,定位原因

线上环境的 JAVA 程序占用太多 CPU 资源&#xff0c;定位原因 top 命令执行显示一下结果 我们可以看到有一个 PID 是 4054 的应用程占用了超过一半的 CPU 资源&#xff0c;这是十分糟糕的事情&#xff0c;这个时候我们首先定位一下他是哪个线程在这里搞事情&#xff0c;这个时…

【JavaSE】认识String类,了解,进阶到熟练掌握

#1024程序员节 | 征文# 下面就让博主带领大家一起解决心中关于String类的疑问吧~~~ 1.字符串构造&#xff1a; 第一种和第二种&#xff08;有一定的区别&#xff0c;在常量池上&#xff09; public static void main(String[] args) { // 使用常量串构造 String s1 "h…

【机器学习】——numpy教程

文章目录 1.numpy简介2.初始化numpy3.ndarry的使用3.1numpy的属性3.2numpy的形状3.3ndarray的类型 4numpy生成数组的方法4.1生成0和1数组4.2从现有的数组生成4.3生成固定范围的数组4.4生成随机数组 5.数组的索引、切片6.数组的形状修改7.数组的类型修改8.数组的去重9.ndarray的…

【Visual Studio】下载安装 Visual Studio Community 并配置 C++ 桌面开发环境的图文教程

引言 Visual Studio 是一个面向 .NET 和 C 开发人员的综合性 Windows 版 IDE&#xff0c;可用于构建 Web、云、桌面、移动应用、服务和游戏。 安装步骤 访问 Visual Studio 的官方下载页面&#xff1a; https://visualstudio.microsoft.com/zh-hans/downloads/运行已下载的 V…

java疫苗发布和接种预约系统源码(springboot)

项目简介 疫苗发布和接种预约系统实现了以下功能&#xff1a; 疫苗发布和接种预约系统的主要使用者分为&#xff1a; 管理员对公告信息&#xff0c;医院信息&#xff0c;疫苗信息&#xff0c;医生信息&#xff0c;用户信息&#xff0c;论坛帖子信息以及预约接种信息等信息进行…

ThinkPad T480拆机屏幕改装:便携式显示器DIY指南

ThinkPad T480拆机屏幕改装&#xff1a;便携式显示器DIY指南 本文记录了将旧笔记本电脑 T480 拆机屏幕改装为便携式显示器的全过程。作者在决定升级设备后&#xff0c;选择通过 DIY 方式利用原有的屏幕资源。文章详细介绍了屏幕驱动板的安装、螺丝孔的剪裁、排线连接及固定的步…

系统性能优化——绑核

简要 绑核正如其名&#xff0c;将线程/进程绑定在一个或多个CPU核心。该技术可以使进程或线程在特定的处理器上运行&#xff0c;而不会被操作系统调度到其他处理器上。这里有两层含义。 如果线程被绑定在指定核心上&#xff0c;则只会在该核心上运行&#xff0c;即使其他核心…

Django自定义过滤器

一、介绍 Django过滤器是一种用于在Django模板中处理数据的技术。它们的主要作用是对模板中的变量进行加工、过滤或格式化&#xff0c;然后返回一个新的值供模板使用。这些过滤器可以在变量输出时&#xff0c;对输出的变量值做进一步的处理&#xff0c;以满足特定的显示需求。…

C# 串口通信教程

串口通信&#xff08;Serial Communication&#xff09;是一种用于设备之间数据传输的常见方法&#xff0c;通常用于与外部硬件设备&#xff08;如传感器、机器人、微控制器&#xff09;进行通信。在 C# 中&#xff0c;System.IO.Ports 命名空间提供了与串口设备交互的功能&…

Golang | Leetcode Golang题解之第508题出现次数最多的子树元素和

题目&#xff1a; 题解&#xff1a; func findFrequentTreeSum(root *TreeNode) (ans []int) {cnt : map[int]int{}maxCnt : 0var dfs func(*TreeNode) intdfs func(node *TreeNode) int {if node nil {return 0}sum : node.Val dfs(node.Left) dfs(node.Right)cnt[sum]if…

数字后端零基础入门系列 | Innovus零基础LAB学习Day6

今天没有具体的数字IC后端lab实验。今天的重点是熟悉掌握静态时序分析STA中的几类timing path以及setup和hold检查机制&#xff08;包含setup和hold计算公式&#xff09;。 芯片流片失败的那些故事 数字后端零基础入门系列 | Innovus零基础LAB学习Day5 等大家把今天内容学习…

设计模式(二)工厂模式详解

设计模式&#xff08;二&#xff09;工厂模式详解 简单工厂模式指由一个工厂对象来创建实例,适用于工厂类负责创建对象较少的情况。例子&#xff1a;Spring 中的 BeanFactory 使用简单工厂模式&#xff0c;产生 Bean 对象。 工厂模式简介 定义&#xff1a;工厂模式是一种创建…

Spring Boot框架下中小企业设备管理系统开发

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理中小企业设备管理系统的相关信息成为必然。…

Kafka-代码示例

一、构建开发环境 File > New > Project 选择一个最简单的模板 项目和坐标命名 配置maven路径 添加maven依赖 <dependencies><!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients --><dependency><groupId>org.apache.kaf…

最长子序列模型二(二分优化版)

文章目录 提高课题解一、拦截导弹二、导弹防御系统三、最长公共上升子序列四、二分函数速写 基础课题解五、最长上升子序列 II 提高课题解 一、拦截导弹 题目链接 第一问非常简单&#xff0c;直接用之前最长上身子序列模板就行 第二问就有难度了&#xff0c;我们要用最少的递…

基于SSM“毛毛宠物店”宠物信息交流平台的设计与实现

开发说明 开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myec…