首页 > 其他分享 >hash哈希表

hash哈希表

时间:2023-04-04 18:56:13浏览次数:36  
标签:叠加 hash 函数 哈希 关键字 地址 key

当我们想在内存中通过关键字寻找特定数据时(键值对),总是希望能快速找到所需数据,在无索引的情况使用二分查找、二叉树、b数也只能在O(lgn)的时间复杂度上查找。

而通过对数据的关键字和其存储位置建立对应关系f,使得每个关键字通过f能唯一确定一个储存位置,那么就能通过对关键字的查找实现O(1)级别的数据查询。

在此,我们称这个对应关系f为哈希函数,以此思想建立哈希表。

哈希函数的构造方法有多种,如:

1.直接定址法

  H(key)=key或H(key)=a*key+b

  该方法映射较为简单,其地址集合和关键字集合大小相同,虽然不会产生冲突,但是很少使用。

2.数字分析法

  通过分析给定数据的特性来建立哈希函数

  比如一组数据:814567,814123,814151...,可以发现该组数据前三位数字一样,后三位数字随机,且均为6位数,那么我们可以取其后三位通过各种方法操作去获得哈希地址。

3.折叠法

  折叠法有移位叠加和间界叠加两种方法,移位叠加是将分割后的每一部分的最低位对齐后相加;间界叠加是从一端向另一端沿分割线来回折叠对齐相加。

  如关键字0442205864,左边是移位叠加,右边是间界叠加。

        5864                5864
        4220                0224
+         04          +       04
—————————————    ——————————————
       10088               6092

4.平方取中法

  将关键字平方后的中间几位为哈希地址。

5.除留余数法

  取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。即H(key)=key%p , (p<=m)

  该方法较为简单,可以对关键字直接取模,也可以将关键字平方取中,折叠等操作后取模。

6.随机数法

  将关键字作为种子产生随机数,取该随机数为哈希地址。


 

当然哈希函数的构造方法远远不止上述几种,实际环境中根据不同需求情况采用不同的哈希函数。

哈希函数不是万能的,其常常会产生冲突。冲突即不同的关键字通过哈希函数映射到了相同的地址。

通常处理哈希冲突的方法有一下几种:

1.开放定址法

  (1)线性探测再散列,即往对应地址后继续寻找空位。

  (2)二次探测再散列,取探测值为1²,-1²,2²,-2²...来回寻找空位。

  (3)伪随机探测再散列,取探测值为伪随机序列。

  需该方法可能产生数据聚集,即同义词均出现在同一片区域

2.再哈希法

  当产生冲突时取不同的哈希函数再次进行计算。该方法不易产生聚集,但是增加了计算时间。

3.链地址法

  将所有关键字为同义词的记录存储在同一线性链表中。

4.建立一个公共溢出区

  所有同义词一旦发生冲突即填入溢出表。


 

大部分哈希函数,在数据量较少的情况下性能较好,不易产生冲突,能实现时间复杂度为O1的快速查找,但当数据量十分庞大的情况下,不建议采用哈希表作为查询方式。

c++中我们经常用unordered_map关联容器来实现哈希表,其内部冲突处理采用链地址法,需注意默认的unordered_map不支持以结构体或类作为键,需重载。

 

参考资料:数据结构(C语言版)---清华大学出版社

 

标签:叠加,hash,函数,哈希,关键字,地址,key
From: https://www.cnblogs.com/Explosion556/p/17287623.html

相关文章

  • 最小覆盖子串(哈希表、字符串)、两数之和(数组、哈希表)、二叉树的层序遍历 II(树、广
    最小覆盖子串(哈希表、字符串)给你一个字符串s、一个字符串t。返回s中涵盖t所有字符的最小子串。如果s中不存在涵盖t所有字符的子串,则返回空字符串""。**注意:**如果s中存在这样的子串,我们保证它是唯一的答案。示例1:输入:s="ADOBECODEBANC",t="ABC"输出:"B......
  • 内网渗透之哈希传递攻击
    (作业记录0x01利用VMware的克隆功能克隆一台win7,取名为win7-2。0x02启用win7和win7-2的系统管理员Administrator账户及设置密码法一启用管理员账号administrator设置密码为123456法二打开开始菜单,右击“计算机”,选择“管理”。在“计算机管理”窗口,依次定位到“本......
  • 对list中的字段进行自定义排序,最后放在LinkedHashMap中
    List<ProjectVO>projectList=dbProjectService.getProjectList();这里面如果第一个字段是如下的顺序:"成都分公司","北京分公司","上海分公司","深圳分公司","广州分公司","重庆分公司"Map<String,List<ProjectVO>>map=projectL......
  • 为什么一个对象重写了equals必须也重写hashCode
    一言以蔽之:重写equals方法是为了比较对象的内容是否相等,重写hashCode方法是为了保证对象在哈希表等数据结构中的正确性。 1、在Java中,如果一个类重写了equals方法,则必须同时重写hashCode方法。这是因为在Java中,对象的hashCode值用于在哈希表(HashTable)等数据结......
  • 有关哈希表简单的散列函数实现-Java实现
    其实现不难,所以直接贴代码:1packagedataSrtuct;23importjava.util.ArrayList;4importjava.util.LinkedList;56publicclassHashTab{7publicstaticvoidmain(String[]args){8hashTablehashT=newhashTable(10);9......
  • 由入门题回想起来的哈希表
    洛谷P2550P2550[AHOI2001]彩票摇奖-洛谷|计算机科学教育新生态(luogu.com.cn)可以看到这是个入门题,完全可以用暴力查找(for循环二重嵌套)来实现,但是这个查找形式让我想起了一个月之前学的哈希表(HashMap)众所周知,利用哈希表可以将查找的时间复杂度优化到O(1)的水平,而且本题需......
  • 四数相加|哈希表
    四数相加给定四个数组,如果四个数相加,如果和为0那么计数加一,最后输出一共有几个组合使得和为0。这题应用哈希表解决对应题目454.四数相加II哈希表使用哈希表,保存前两个数组对应的组合之和。value为两数相之和,如果有相同那么value加一。之和再遍历剩下两个数组之和的组合,再......
  • HashMap
    HashMap变化HashMap1.7在JDK1.7到JDK1.8的时候,对HashMap做了优化首先JDK1.7的HashMap当出现Hash碰撞的时候,最后插入的元素会放在前面,这个称为“头插法”JDK7用头插是考虑到了一个所谓的热点数据的点(新插入的数据可能会更早用到),但这其实是个伪命题,因为JDK7中rehash的时......
  • Java 敞 HashCode
    HashCode算法长话短说,Java的Object.hashCode()实现算法,据get_next_hash所述,可选方案有多种,默认为5.>java-XX:+UnlockExperimentalVMOptions-XX:+PrintFlagsFin......
  • 手撕HashMap(二)
    这里再补充几个手撕HashMap的方法1、remove()remove方法参数值应该是键值对的键的值,当传入键值对的键的时候,remove方法会删除对应的键值对需要利用我们自己先前创......