Hash表函数设计和冲突的解决

2023-05-16

转自:http://hi.baidu.com/wwwanq/blog/item/91688d0eb39bebe4aa645756.html 

 

 

     hash定义了一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法。由于通过更短的哈希值比用原始值进行数据库搜索更快,这种方法一般用来在数据库中建立索引并进行搜索,同时还用在各种解密算法中。

  设所有可能出现的关键字集合记为u(简称全集)。实际发生(即实际存储)的关键字集合记为k(|k|比|u|小得多)。|k|是集合k中元素的个数。
  散列方法是使用函数hash将u映射到表t[0..m-1]的下标上(m=o(|u|))。这样以u中关键字为自变量,以h为函数的运算结果就是相应结点的存储地址。从而达到在o(1)时间内就可完成查找。
  其中:
  ① hash:u→{0,1,2,…,m-1} ,通常称h为散列函数(hash function)。散列函数h的作用是压缩待处理的下标范围,使待处理的|u|个值减少到m个值,从而降低空间开销。
  ② t为散列表(hash table)。
  ③ hash(ki)(ki∈u)是关键字为ki结点存储地址(亦称散列值或散列地址)。
  ④ 将结点按其关键字的散列地址存储到散列表中的过程称为散列(hashing).
  比如:有一组数据包括用户名字、电话、住址等,为了快速的检索,我们可以利用名字作为关键码,hash规则就是把名字中每一个字的拼音的第一个字母拿出来,把该字母在26个字母中的顺序值取出来加在一块作为改记录的地址。比如张三,就是z+s=26+19=45。就是把张三存在地址为45处。
  但是这样存在一个问题,比如假如有个用户名字叫做:周四,那么计算它的地址时也是z+s=45,这样它与张三就有相同的地址,这就是冲突,也叫作碰撞!
  冲突:两个不同的关键字,由于散列函数值相同,因而被映射到同一表位置上。该现象称为冲突(collision)或碰撞。发生冲突的两个关键字称为该散列函数的同义词(synonym)。
  冲突基本上不可避免的,除非数据很少,我们只能采取措施尽量避免冲突,或者寻找解决冲突的办法。影响冲突的因素
  冲突的频繁程度除了与h相关外,还与表的填满程度相关。
  设m和n分别表示表长和表中填人的结点数,则将α=n/m定义为散列表的装填因子(load factor)。α越大,表越满,冲突的机会也越大。通常取α≤1。
  散列函数的构造方法:
  1、散列函数的选择有两条标准:简单和均匀。
  简单指散列函数的计算简单快速;
  均匀指对于关键字集合中的任一关键字,散列函数能以等概率将其映射到表空间的任何一个位置上。也就是说,散列函数能将子集k随机均匀地分布在表的地址集{0,1,…,m-1}上,以使冲突最小化。
  2、常用散列函数
  (1)直接定址法:比如在一个0~100岁的年龄统计表,我们就可以把年龄作为地址。
  (2)平方取中法
  具体方法:先通过求关键字的平方值扩大相近数的差别,然后根据表长度取中间的几位数作为散列函数值。又因为一个乘积的中间几位数和乘数的每一位都相关,所以由此产生的散列地址较为均匀。
  (3)除留余数法
  取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。该方法的关键是选取m。选取的m应使得散列函数值尽可能与关键字的各位相关。m最好为素数(4)随机数法
  选择一个随机函数,取关键字的随机函数值为它的散列地址,即
  h(key)=random(key)
  其中random为伪随机函数,但要保证函数值是在0到m-1之间。
  处理冲突的方法:
  1、开放定址法
  hi=(h(key)+di) mod m i=1,2,...,k(k<=m-1)
  其中m为表长,di为增量序列
  如果di值可能为1,2,3,...m-1,称线性探测再散列。
  如果di取值可能为1,-1,2,-2,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2)
  称二次探测再散列。
  如果di取值可能为伪随机数列。称伪随机探测再散列。开放地址法堆装填因子的要求
  开放定址法要求散列表的装填因子α≤l,实用中取α为0.5到0.9之间的某个值为宜。
  ②二次探查法(quadratic probing)
  二次探查法的探查序列是:
  hi=(h(key)+i*i)%m 0≤i≤m-1 //即di=i2
  即探查序列为d=h(key),d+12,d+22,…,等。
  该方法的缺陷是不易探查到整个散列空间。
  ③双重散列法(double hashing)
  该方法是开放定址法中最好的方法之一,它的探查序列是:
  hi=(h(key)+i*h1(key))%m 0≤i≤m-1 //即di=i*h1(key)
  即探查序列为:
  d=h(key),(d+h1(key))%m,(d+2h1(key))%m,…,等。
  该方法使用了两个散列函数h(key)和h1(key),故也称为双散列函数探查法。
  2、拉链法
  拉链法解决冲突的方法
  拉链法解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组t[0..m-1]。凡是散列地址为i的结点,均插入到以t为头指针的单链表中。t中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。
  3、建立一个公共溢出区
  假设哈希函数的值域为[0,m-1],则设向量hashtable[0..m-1]为基本表,另外设立存储空间向量overtable[0..v]用以存储发生冲突的记录。
  性能分析
  插入和删除的时间均取决于查找,故下面只分析查找操作的时间性能。
  虽然散列表在关键字和存储位置之间建立了对应关系,理想情况是无须关键字的比较就可找到待查关键字。但是由于冲突的存在,散列表的查找过程仍是一个和关键字比较的过程,不过散列表的平均查找长度比顺序查找、二分查找等完全依赖于关键字比较的查找要小得多。
  (1)查找成功的asl
  散列表上的查找优于顺序查找和二分查找。
  (2) 查找不成功的asl
  对于不成功的查找,顺序查找和二分查找所需进行的关键字比较次数仅取决于表长,而散列查找所需进行的关键字比较次数和待查结点有关。因此,在等概率情况下,也可将散列表在查找不成功时的平均查找长度,定义为查找不成功时对关键字需要执行的平均比较次数。
  注意:
  ①由同一个散列函数、不同的解决冲突方法构造的散列表,其平均查找长度是不相同的。
  ②散列表的平均查找长度不是结点个数n的函数,而是装填因子α的函数。因此在设计散列表时可选择α以控制散列表的平均查找长度。
  ③ α的取值
  α越小,产生冲突的机会就小,但α过小,空间的浪费就过多。只要α选择合适,散列表上的平均查找长度就是一个常数,即散列表上查找的平均时间为o(1)。
  ④ 散列法与其他查找方法的区别
  除散列法外,其他查找方法有共同特征为:均是建立在比较关键字的基础上。其中顺序查找是对无序集合的查找,每次关键字的比较结果为"="或"!="两种可能,其平均时间为o(n);其余的查找均是对有序集合的查找,每次关键字的比较有"="、"<"和">"三种可能,且每次比较后均能缩小下次的查找范围,故查找速度更快,其平均时间为o(lgn)。而散列法是根据关键字直接求出地址的查找方法,其查找的期望时间为o(1)。 
  例子:例子:选取哈希函数h(k)=(3k)%11,用线性探测再散列法处理冲突。
  试在0~10的散列地址空间中,对关键序列22,41,53,46,30,13,01,67构造哈希表,并求等概率情况下查找不成功的平均查找长度asl。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hash表函数设计和冲突的解决 的相关文章

  • Bool.hashValue 转换为 Int 有效吗?

    在某些情况下和一些代码我看到hashValue用于转换Bool to Int 然而 代码 let someValue true let someOtherValue false print someValue hashValue print
  • (java) - 哈希函数在给定范围内均匀分布字符串?

    所以 我正在寻找一个哈希函数 假设没有输入倾斜 将 最多 16字节的非空字符串 合理地均匀地 分布到一个范围上 0 n where n是用户输入 但不会随时间变化 And我应该能够争论why该函数应该提供 相当均匀 的分布 最后 我所需要的
  • 在这种情况下是否可以创建一个最小完美哈希函数?

    我想创建一个哈希映射 或其他结构 如果您有任何建议 来存储键值对 这些键将在创建地图的同时一次性插入 但我不知道键是什么 任意长度的字符串 直到运行时 当我需要创建地图时 我正在解析这样的查询字符串 x 100 name bob color
  • Perl DBI fetchall_hashref

    考虑下表 mysql gt select from vCountryStatus CountryName CountryISO Code Status Symbol CurrencyName Brazil BR 55 LIVE BRL Br
  • 按月和年将日期的 Ruby 数组分组为哈希

    假设我有一个 Ruby 数组Dates like 2011 01 20 2011 01 23 2011 02 01 2011 02 15 2011 03 21 创建按年和按月对日期元素进行分组的哈希的简单且 Ruby 式的方法是什么 例如
  • 获取文件哈希性能/优化

    我正在尝试尽快获取文件的哈希值 我有一个程序 可以对大量数据 100GB 进行哈希处理 这些数据由随机文件大小 每个文件从几KB到5GB 组成 跨少量文件到数十万个文件 该程序必须支持所有 Java 支持的算法 MD2 MD5 SHA 1
  • PHP - 以某种方式哈希对象,具有相同字段值的不同对象具有相同的哈希值

    我正在寻找一种方法来为 PHP 对象生成某种哈希值 通用解决方案 如果可能的话 可以使用所有分类的 内置的和自定义的 SplObjectStorage getHash 不是我正在寻找的 因为它会为给定类的每个实例生成不同的哈希值 为了描述这
  • 将 JavaScript 中的大字符串与哈希进行比较

    我有一个带有文本区域的表单 其中可以包含使用多个第三方富文本编辑器之一编辑的大量内容 例如博客文章 我正在尝试实现类似自动保存功能的功能 如果内容发生更改 它应该通过ajax 提交内容 然而 我必须解决这样一个事实 我作为选项的一些编辑器不
  • 如何将目录路径转换为唯一的数字标识符 (Linux/C++)?

    我正在研究获取目录 文件夹 并派生某种形式的唯一数字标识符的方法 我研究了 字符串到哈希 方法 但是 鸽子洞原理 http www codinghorror com blog 2007 12 hashtables pigeonholes a
  • java中带有二维键的映射

    我想要一个在 Java 中由两个键索引的映射 在其中使用两个键放置和检索值的映射 需要明确的是 我正在寻找以下行为 map put key1 key2 value map get key1 key2 returns value map ge
  • Perl 使用什么哈希函数/算法?

    有人能解释一下 Perl 用于将字符串映射到索引的哈希函数 算法吗 有相关读物吗 这个答案早于 5 28 中进行的哈希函数更改 请参阅 默认哈希函数更改 perldelta 为 5 28 http perldoc perl org perl
  • 使用哈希检查具有 $_POST 值的页面是否已刷新

    当将表单发布到同一个PHP页面时 正确的方法是什么来查找页面是否被意外刷新而不是再次提交 这是我现在正在使用的 tmp implode POST myHash md5 tmp if isset SESSION myHash SESSION
  • 为什么 Java 中的 hashCode() 可以对不同对象返回相同的值?

    引用我正在读的书中的一段话首先Java http www amazon co uk Head First Java Kathy Sierra dp 0596009208 关键是 哈希码可以相同 但不一定保证对象相等 因为使用的 哈希算法 h
  • Rails 4 - 将地址保存为数据库中的一列

    我是 Rails 新手 正在开发一个简单的应用程序 我的 ERD 中有一个名为 Client 的模型 并且希望保存每个客户的地址 我最初的想法是将地址保存为单独的字段 即 rails g model Client address first
  • 各个平台对 SHA-2 的支持情况如何?

    我读到 SHA 1 即将从 FIPS 180 2 标准中退役 http gcn com articles 2010 03 03 rsa sha competition aspxhttp gcn com articles 2010 03 03
  • 防止 .exe 时间戳发生变化

    有谁知道如何防止可执行文件的时间戳更改 我正在尝试为 exe 生成一致的哈希代码 但我认为时间戳可能会阻止这种情况发生 每次我重新编译代码 VS C 时 FastSum 都会生成不同的校验和 Thanks PE 文件格式 如 EXE 中 具
  • 哈希表的空间复杂度是多少?

    具有 32 位键和指向单独存储的值的 32 位指针的哈希表的大小是多少 是 2 32 个槽 4 字节 键 4 字节 指向值的指针 4 10 9 4 4 32GB 我想了解哈希表的空间复杂度 我认为你问错了问题 数据结构的空间复杂度表示它占用
  • iPhone 和加密库

    我想我必须在我的 iPhone 应用程序中使用加密库 我想问你有关苹果公司实施的加密货币出口政策的影响 我需要做一些额外的事情吗 例如填写表格等 1 如果我使用 MD5 进行哈希处理 2 如果我使用对称加密 Thanks EDIT 2009
  • 使用 crypt() 加密

    我目前正在做一个非常安全的登录系统 但我是 crypt 函数的新手 需要一些快速帮助 我在注册过程中使用 crypt 加密密码字符串并将其保存到数据库中 但是 我如何在登录过程中解密密钥 或者我应该怎么做 或者是否可以对提交的密码字符串进行
  • PHP 的password_verify() 是否可以抵御极长的密码(DoS 攻击)?

    一般攻击场景 2013 年 Django 存在一个普遍漏洞 攻击者可以通过非常大的密码创建极其密集的 CPU 计算 请参阅此处的安全通知 https www djangoproject com weblog 2013 sep 15 secu

随机推荐

  • Cmake在windows支持预编译头文件(stdafx.h)

    最近一直在研究cmake构建项目 xff0c 之前接触cmake的时候就感觉不太喜欢cmake xff0c 觉得它太乱了 xff0c 产生了太多的中间文件 xff0c 产生的项目文件也不是特别友好 xff0c 在windows下 xff0c
  • 位置控制代码

    Copyright c 2013 2016 PX4 Development Team All rights reserved Redistribution and use in source and binary forms with or
  • 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。

    最近公司开发网站针对微信公众号的支付功能 由于公司目前的这个项目网站是使用asp代码开发的 xff0c 但是微信官方给出的demo中是没有asp版本的 xff0c 所以楼主只有下载demo的php版本作为参考写了一个asp版本的代码 阅读官
  • Nacos实战一:架构及部署

    2018年 xff0c 阿里巴巴开源 Nacos xff0c 由此成为继 Eureka Consul Apollo 等服务注册发现 amp 配置的又一开源框架 xff0c 到如今2021年 xff0c Nacos 已经历了 0 01 gt
  • Windows Server搭建Tomcat服务器及Java项目应用

    Windows Server搭建Tomcat服务器及Java项目应用 本文主要介绍使用阿里云Windows Server搭建Tomcat服务器及Java项目应用 xff0c 将文章写下来以后自己也可以及时看看 工具和软件 服务器 xff1a
  • 【Node.js】安装使用nvm管理nodejs版本

    Node js 安装使用nvm管理nodejs版本 本文主要介绍mac linux下如何安装nvm来管理nodejs版本 一 下载nvm安装 方式一 xff1a brew方式 1 xff1a brew list nvm 命令检测是否安装nv
  • Redis设置Key/value的规则定义和注意事项(附工具类)

    Redis设置Key value的规则定义和注意事项 xff08 附工具类 xff09 对于redis的存储key value键值对 xff0c 经过多次踩坑之后 xff0c 我们总结了一套规则 xff1b 这篇文章主要讲解定义key va
  • Linux命令之mkdir

    mkdir命令用于创建目录 xff0c 全拼 xff1a make directory 具体参数 xff1a m 选项自定义目录权限 p 递归建立目录 v 创建文件夹时显示信息
  • 浅析微信支付:支付结果通知

    本文是 浅析微信支付 系列文章的第六篇 xff0c 主要讲解支付成功后 xff0c 微信回调商户支付结果通知的处理 浅析微信支付系列已经更新五篇了哟 xff5e xff0c 没有看过的朋友们可以看一下哦 浅析微信支付 xff1a 统一下单接
  • 浅析微信支付:查询订单和关闭订单

    本文是 浅析微信支付 系列文章的第七篇 xff0c 主要讲解微信商户平台的订单查询和关闭接口的使用 浅析微信支付系列已经更新六篇了哟 xff5e xff0c 没有看过的朋友们可以看一下哦 浅析微信支付 xff1a 支付结果通知 浅析微信支付
  • 超实用!!!使用IDEA插件Alibaba Cloud Toolkit工具一键部署本地应用到ECS服务器

    最近看到阿里云发布了一款名为 Alibaba Cloud Toolkit 的插件 xff0c 可以帮助开发者高效开发并部署适合在云端运行的应用 xff0c 瞬间击中了我的小心脏 xff0c 这个对于个人开发者来说超级棒啊 xff0c 终于不
  • 浅析微信支付:开通社交立减金活动、创建立减金及领取使用的相关文档和源码

    本文是 浅析微信支付 系列文章的第十七篇 xff0c 主要讲解在在微信平台中 xff0c 如何创建优惠券 xff0c 开通社交立减金 xff0c 并为用户配置发送立减金 上篇文章已经为大家讲解了如何在微信公众平台创建优惠券并为用户发券 xf
  • vnc远程屏幕大小设置

    安装软件tigervnc server yum install vnc y 注释 etc sysconfig vncservers VNCSERVERS 61 34 1 root 34 VNCSERVERARGS 1 61 34 geome
  • tx2系统备份与恢复

    tx2系统备份与恢复 tx2系统备份与恢复对我们以后长期开发与产品批量生产是非常有帮助的 xff0c 能快速的对已经开发好的系统进行备份 xff0c 复制 xff0c 节约大量的安装时间 在操作过程在需要手动操作 xff0c 执行命令也不多
  • STM32串口中断的方式发送

    我将其改为真正的中断发送 步骤一 xff1a 初始化GPIO GPIO InitTypeDef GPIO InitStructure GPIO InitStructure GPIO Pin 61 GPIO Pin 10 LED1 PC10
  • OLT光网络小笔记

    OLT上配置 xff1a link aggregation 0 6 1 1 2 1 egress ingress workmode lacp staic 0框6槽1口和1框2槽1口绑定的意思 上联交换机上配置 xff1a int eth t
  • VS2012,VC++无法找到头文件或库函数.无法打开包括文件:“iostream”: No such file or directory

    卸载VS2010后 xff0c 安装VS2012 xff0c 随便创建个VC控制台项目 xff0c 编译提示连 34 iostream 34 和 stdio h 之类的头文件或库文件都无法找到 xff0c 重装VS2012后依然无法编译 x
  • C语言高手进阶的三碟小菜和一盘大餐

    前段时间一直到现在正在看的几本书 xff0c 觉得真心不错 xff0c 给很多朋友都推荐过 xff0c 现在正好赶上这个活动 xff0c 也分享一下 首先说明一下的是 xff0c 这次推荐的书都是进阶用的 xff0c 学完这几本书再辅以在实
  • 操作系统-调度算法

    1 xff1a 先来先服务调度算法 FCFS 1 按照作业提交 xff0c 或进程变为就绪状态的先后次序分派CPU 2 新作业只有当当期那作业或进程执行完成或阻塞才获得CPU运行 3 被唤醒的作业或进程不立即恢复执行 xff0c 通常等到当
  • Hash表函数设计和冲突的解决

    转自 xff1a http hi baidu com wwwanq blog item 91688d0eb39bebe4aa645756 html hash定义了一种将字符组成的字符串转换为固定长度 一般是更短长度 的数值或索引值的方法 x