浅谈哈希表与其映射函数(哈希函数)

第四讲. 经典算法之哈希映射 第四讲. 经典算法之哈希映射1. 简介2. 从一个简单例题开始3. 哈希中的碰撞冲突3.1 线性探测法3.2 链地址法3.3 再哈希法3.4 ...4. 哈希函数的设计4.1 更大的哈希表4.2 更好的哈希运算5. 最后说几句 1. 简介 哈希即Hash,一般翻译为散列的意思,简单而言其实就是通过一个函数,将一个值映射成另一个更好的值。 这个更好,是一个比较抽象的概念。可以是把一个很大的数,映射到... 阅读详情

哈希表又称散列表,通过把关键字key映射到数组中的一个位置来访问记录。映射过程通过函数实现,而这个函数就叫哈希函数,存放关键字的数组称为散列表。

哈希表结构

这里写图片描述

前面说了,关键字是存放在数组中的,所以哈希表的结构其实就是一个数组,为什么要采用数组来作为哈希表的数据结构呢?这里我不得不说数组的一些特性。
数组的时间复杂度是O(1),这里说的时间复杂度是访问复杂度,不是遍历复杂度。计算机内存被设定为直接访问任意一个地址的时间是一致的,结合该特性,我们知道数组在内存中的存储是,数组名存放在栈内存中,保存数组第一个元素的地址,而数组本身存放在堆内存中,其存储空间是连续的,所以我们只需要知道数组名就可以非常快速的定位数组任意位置。

哈希算法

哈希算法的作用是将关键字通过一系列计算,得出的结果作为数组下标,然后再将关键字存放到该下标对应的位置。哈希算法是决定哈希表中元素排列结构的最主要因素,不同的哈希算法会导致同样的数据出现不同的存储顺序。针对不同类型的关键字哈希算法也不同。下面是针对整数关键字的几种哈希算法(如果关键字是字符串,也可将字符串所有字符的ASCII码加起来得到一个整数再进行计算):
直接取余:顾名思义,直接取余法是用关键字除以一个固定值取余数,一般这个固定值取哈希表的大小。如果一个哈希表的大小是16,那么关键字100的存放位置应该是数组下标为4的位置。

乘积取整:成绩取整法是用关键字乘以一个常数A(0<A<1),然后取乘积的小数部分再与哈希表的大小求积,最后取结果的整数部分。同上,若哈希表的大小为16,A取0.025,那么关键字100的存放位置应该是数组下标为8的位置。
上面提到的两种算法都非常简单,但都存在很大的问题,这两种算法在某种程度上都会产生大量的冲突,即不同的数通过算法得出的结果相同,这样会令哈希的效果大打折扣。下面介绍一种解决冲突非常有效的哈希算法,经典哈希算法Time33

uint32_t time33(char const *str, int len) 
    { 
        unsigned long  hash = 0; 
        for (int i = 0; i < len; i++) { 
            hash = hash *33 + (unsigned long) str[i]; 
        } 
        return (hash & 0x7FFFFFFF); 
    }

从代码中我们可以看出,这种算法就是将关键字每一位拿出来,逐个相加,每相加一次都乘以33,最终获得我们要的结果。该算法可最大程度防止冲突的发生,亦可避免字符串类型的关键字顺序不同而所含字符相同导致计算结果相同(如adcfg和dcfga)。在php中,一个字符串长度过长不好计算,我们可以将其先利用MD5加密转化为32位的字符串,然后再对这个字符串进行计算即可。

在学习Time33之前,我自己也想过一个避免该类问题的算法,供大家讨论,思想如下:
这里写图片描述
如图,针对一个关键字,我们可对其从1开始进行依次编号,然后取每一位的值或者ASCII码值与它所对应的编号相乘,最后求和。这种方法与Times33类似,都可以有效的解决大量冲突问题,但是仍避免不了一些及特殊的情况。为了防止这些哈希算法无法避免的冲突,所以人们开始从哈希表的结构下手,希望通过改变哈希表的结构来避免这些冲突,因此又出现了许多避免冲突的方法,如“拉链法”解决冲突。

“拉链法”解决冲突的做法是将所有哈希值相同的关键字节点链接在同一个链表中。如下图:

这里写图片描述

“拉链法”将哈希值相同的关键字通过链表的方式连接起来,确实有效的解决了冲突问题,但是在查询关键字的时候,若所查询的位置无冲突,那么查询的时间复杂度为O(1),但如果所查询的位置出现冲突,就需要进一步遍历链表去查询,这样的话查询的效率大打折扣,时间复杂度并不能满足所谓的O(1),所以说哈希表只能在理想无冲突的情况下,时间复杂度才能到达O(1)。因此来看,要降低时间复杂度最终的瓶颈还是在怎么防止冲突的问题上而不是出现冲突怎样处理的问题上。但是并不产生冲突几乎是不可能实现的,那么有没有一种办法既能有效处理出现的冲突,又能优化时间复杂度呢?我不知道现在有没有这种方法,但是我提供一种思路供大家思考,这种思路叫“二次散列”。

“二次散列”,说白了就是对每一个关键字都进行两种不同形式/函数的散列,然后根据两次的结果确定该关键字的位置(如果两个不同的关键字通过哈希函数A算出的哈希值相等,那么他们通过哈希函数B所算出的哈希值几乎不可能相等,哈希函数A和B可自行决定,但是最好取两种散列思路不同的算法)。而存储方式就叫“坐标法”,跟”拉链法”大体相似,不同的是,”拉链法”采用链表储存冲突,“坐标法”利用数组存储冲突。该结构的特点是它有一个纵向数组,类似于哈希表的原始结构,纵向数组每一位对应一个横向数组(横向数组命名应为编号式,下划线后的数字为所对应的纵向数组下标,如M_0[]、M_1[]….),第一次散列所计算出哈希值为纵向数组下标,若该位置为空说明无冲突发生,直接存储;若有值,判断是否相等,若不等说明冲突,先为该下标申请其所对应的横向数组,然后进行第二次散列,第二次散列所对应的哈希值为横向数组的下标,也就是该关键字所要存放的位置,类似于X/Y轴,查询的时候最多只需做两次散列一次比较,就可以确定关键字的具体位置。为什么不直接使用二维数组呢?因为毕竟不是所有位置都会发生,使用二维数组会过度消耗内存空间。该方法还是存在很多缺陷,只提供一个思考的方向。

总的来说,散列函数的好坏是决定哈希表性能的关键,一个好的哈希函数一定具备两个特性,一是足够聚集,二是不重叠,这样即保证了内存的有效利用也保证了查询的时效,但这两个特性在理论上相悖,只能去找一个平衡点,使性能最大化。

浅谈Python数据结构(六)--哈希表 最近学习了python数据结构,做一些必要的笔记,一来是对自己学习的知识的巩固,二来对有同样问题的人有参考作用 文章目录一 定义二 演变过程三 解决冲突的方法四 哈希表的应用五 哈希表模拟set六 总结 一 定义 哈希表是普通数组概念的推广,是能够根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(Hash Function),存放记录的数组叫做散列表(Hash Table)。 在平均情况下,. 阅读详情

相关推荐

C++ 哈希函数:详解与实现

哈希函数是一个将任意大小的数据映射到固定大小值的函数。通过哈希函数,我们可以将数据映射为一个哈希码或哈希值,这个值可以用来表示数据或者用于查找、比较等操作。哈希函数的设计目标是尽量将输入数据均匀地映射到哈希值的范围内,以减少冲突。哈希函数在C++编程中扮演着重要的角色,它们用于将数据映射为固定大小的哈希值,以实现高效的数据存储和检索。本文介绍了哈希函数的概念、原理和常见的实现算法,并提供了一个简单的哈希表示例供参考。

2301_79330511的博客 492

【转】HashMap

【转】HashMap转载自摘要简介内部实现存储结构-字段功能实现-方法1.确定哈希桶数组索引位置2.分析HashMap的put方法3.扩容机制线程安全性JDK1.8与JDK1.7的性能对比Hash较均匀的情况Hash极不均匀的情况小结 转载自 美团技术团队.Java 8系列之重新认识HashMap 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树

weixin_45299950的博客 252

audio框架学习-Audio_Flinger分析

文章目录一、代码位置二、audio服务启动2.1 main服务2.2 audioflinger添加到系统服务中2.3 audioflinger的对外接口 之前记录过audioTrack的笔记,这次继续参考audioFlinger相关的代码并做笔记; 参考文档:https://www.cnblogs.com/innost/archive/2011/01/15/1936425.html和https://blog.youkuaiyun.com/zyuanyun/article/details/60890534?spm=100

永不秃头的程序员的博客 2135

Hash魔法:分布式哈希算法

我们从浅入深一步一步介绍什么是分布式哈希表。 哈希函数 哈希函数是一种计算方法,它可以把一个值A映射到一个特定的范围[begin, end]之内。对于一个值的集合{k1, k2, … , kN},哈希函数把他们均匀的映射到某个范围之中。这样,通过这些值就可以很快的找到与之对应的映射地址{index1, index2, … , indexN}。对于同一个值,哈希函数要能保证对这个值的运算

wangpengqi的专栏 1873

《炬丰科技-半导体工艺》用于半导体的RCA清洁技术

书籍:《炬丰科技-半导体工艺》 文章:用于半导体的RCA清洁技术 编号:JFKJ-21-1073 引言 RCA清洗技术是用于清洗硅晶圆等的技术,由于其高可靠性,30多年来一直被用于半导体和平板显示器(FPD)领域的清洗。其基础是以除去颗粒为目的的氨水-过氧化氢溶液组成的SC―1洗涤和以除去金属杂质为目的的盐酸-过氧化氢溶液组成的SC―2洗涤相结合的洗涤技术。SC-1洗涤的机理说明如下。首先,用过氧化氢氧化硅晶片的表面,用作为碱的氨蚀刻氧化硅,并通过剥离去除各种颗粒。此外,如图1所示,在pH 10.5附近的S

jfkj2021的博客 769

LSTM预测股票数据---数据预处理

# 导入相应的模块 import pandas as pd import numpy as np import matplotlib.pyplot as plt import tensorflow as tf # 获取训练集 def get_train_data(data,batch_size = 60 ,time_step = 20,train_begin = 0,train_end = 58...

qq_35358021的博客 3360

hash算法的作用是什么?

Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。 Hash算法在信息安全方面的应用主要体现在以下的3个方面: 1) 文件校验 我们比较熟悉的校

zealot_2002的专栏 2987

电路方案分析(十二)USB Type-C PD 移动电源参考设计方案

TPD8S300为USB Type-C连接器的CC1,CC2,SBU1和SBU2引脚集成了四个通道的20v短到vbus和过压保护。TPD8S300集成了八个IEC61000-4-2ESD保护通道,用于USB Type-C连接器的CC1、CC2、SBU1、SBU2、DP_T (顶侧D-) 、DM_T (顶侧D-) 、DP_B (底侧D-) 引脚。当电源组是接收器并为其自身的电池充电时,该芯片会对电池充电,而在电源模式期间,该芯片充当DC-DC转换器以生成VBUS。

小幽余生不加糖 2万+

浅谈哈希表(HashTable)——拉链法、哈希桶、Probing探测方法

概述 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f...

jasonLee的博客 4308

Field Characteristics 深入解析,理解 SAP ABAP Analytics 中 Dimension 与 Measure 的真正边界

在SAP ABAP Analytics数据模型中,字段应建模为Dimension还是Measure,关键在于业务语义而非数据类型。Dimension提供分析上下文,构成数据坐标系,支持钻取与切片;Measure则需具备明确聚合语义(如#SUM、#MIN、#MAX),且必须满足Distinct(无重复)与Complete(无缺失)原则,确保聚合结果准确。错误的建模会导致聚合偏差,根源常在事实粒度不清或关联关系不当。因此,正确划分字段角色,本质是让Analytical Engine准确理解业务数据的分析逻辑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 57

5、流体-结构相互作用耦合技术详解

本文详细解析了流体-结构相互作用(FSI)的两种核心耦合技术:松散耦合和紧密耦合。通过原理阐述、优缺点分析及实际应用案例,对比了两种方法的适用场景与性能差异,并进一步探讨了高级耦合技术的发展趋势和工程实践方向,为相关领域的研究人员和工程师提供了全面的技术参考。

fanta的博客 205

哈希表

浅谈算法和数据结构: 十一 哈希表 摘自:https://www.cnblogs.com/yangecnu/p/Introduce-Hashtable.html 在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的...

qq_39474604的博客 185

【自适应调制】自适应调制解调通信链路误码率matlab仿真与分析

BPSK中的B是“Binary”的意思,也就是有两个变化状态,比如说相位上的“+90°(代表1)、-90°(代表0)”,一个状态代表的就是一个比特。QPSK的“Q”是“Quadrature”的意思,有四个变化状态,如相位上的“+45°(代表00)、-45°(代表11)、+135°(代表10)、-135°(代表01)”,那么一个状态就代表两个比特的信息,如图2所示。同理8PSK的一个状态代表三个比特。但是功率资源并不是无限的,基站总的发射功率是一定的,为了充分利用所有的功率,采用的就是AMC技术。

FPGA/MATLAB学习教程/源码/项目合作开发 1833

浅谈算法和数据结构: 十一 哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度。 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) ...

125

国科大作业考试资料《人工智能原理与算法》2024新编-第二次作业整理

1、对于下列活动,分别给出任务环境的PEAS描述, 并按2.3.2节列出的性质进行分析: 3、为图2.2中描述的吸尘器世界实现一个可以进行性能度量的环境模拟器。你的实现是必须是模块化的,以使传感器、执行器和环境特征(大小、形状、灰尘放置等)便于修改。 4、实现上述题目真空吸尘器环境中的简单反射Agent。用所有可能的初始灰尘分布和Agent位置,运行环境模拟器和Agent。记录Agent在每种情况下的性能评分和总体平均评分。

MatsumotoChrikk 1187

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

浅谈哈希表

                                       浅谈哈希表     之前学过hash表,当时对哈希表的的了解不是很深,经过这几天的深入分析,现在算是对哈希表有了一个比较浅的了解,下面就简单的谈一下我对哈希表的了解,以后肯定还会对它进行深入的分析.什么是哈希表?     散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据...

小鱼儿的博客 228

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

浅谈算法和数据结构:哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是它们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度。 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) 什么是哈希表 哈希表就

一个程序猿的故事 2921

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

浅谈算法和数据结构(11):哈希表

原文出处: 寒江独钓    在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是它们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度。 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table)

sam的blog 1593

浅谈算法和数据结构: 哈希表

作者: yangecnu(yangecnu's Blog on 博客园)  出处:http://www.cnblogs.com/yangecnu/  http://www.cnblogs.com/yangecnu/p/Introduce-Hashtable.html 基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况

BinChasing的博客 2276
上一篇: 网易游戏-平台开发工程师-一面(电话面试)
下一篇: InnoDB-MVCC与乐观锁
Jeaforea
博客等级 码龄10年 30粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值