散列之HashTable学习
1,什么是散列?
举个例子,在日常生活中,你将日常用品都放在固定的位置,当你下次需要该东西时,直接去该地方取它。这个过程就相当于散列查找。
若将它们随意杂乱无章地存放,当需要某件东西时,只能一个地方一个地方地逐一查找,这就相当于顺序查找。
在数据结构中,数组就相当于一张散列表,因为可以根据数组下标索引直接取得该位置上的元素。
2,什么情况下用到散列?
由于散列查找相对于其它查找而言,理论上只需要O(1)时间就可以找到某元素,因此,当查找是主要的任务时,散列就是实现词典的一种很好的选择。
3,散列函数的理解
散列查找中,需要提供一个查找键,根据该查找键来寻找值---(KEY,VALUE)....而在实际应用中,查找键描述的是现实世界中对象的性质,它不合适直接用来作为Value(值)的索引(索引一般是整数)。其次,查找键的范围可能很大,但是计算机的存储是空间使用得越少越合理。基于以上两个原因,需要使用散列函数将查找键转化为某个元素的索引。对于一个典型的散列函数,执行以下两个步骤:
①将查找键转换为一个称为散列码的整数-------解决索引问题
②将散列码压缩到散列表的索引范围------解决存储空间限制
4,在Java中,JDK类库String类的对象的hashCode是这样生成的:
对于字符串s而言,它的hashCode是基于每个字符unicode值乘以一个基于该字符在字符串中位置的因子g(其中 g=31)
如: s = u(0)u(1)……u(n-1)
散列码hash = u(0)*g^(n-1) + u(1)*g^(n-2)+……+u(n-2)*g+u(n-1),该多项式使用 Horner方法 可以写成一种等价的代数形式。该代数形式的多项式求值用程序表示如下:
int hash = ;
int n = s.length();
for(int i = ; i < n; i++)
hash = g*hash + s.charAt(i);
5,JDK中对于64位long类型对象作为key的hashCode码按照如下方法生成:
int(key^(key>>32))
key一共有64位,首先将key右移32位(高32位补0),原来的key低32位的值被丢弃,再进行异或运算,就可以合并64位查找键的低32位的值和高32位的值(key中高32位的bit与低32位的bit异或),再运行强制类型转换,将结果转化成32位的值。这样就可以将一个64位的key结合它的每一位的值来获得一个32位的hashCode散列码。
6,散列表长度问题
散列表的长度不能为偶数,why?因为在将散列码压缩为散列表的索引时,通常是使用取模计算---c%n(c 为散列码,n 为散列表长度)
当 n 为偶数时,c%n 的奇偶性与 c 的奇偶性相同,若散列码偏向于奇数或者偶数(内存地址的散列码通常是偶数)这样得到的索引很难是均匀分布的。因此散列表的长度通常取奇数,最好取素数。
7,散列冲突的处理
这个知识点可以单独写一篇文章了。当在词典中插入元素时,若散列函数将查找键映射到一个已经使用的位置,则需要为该查找键相关联的值寻找另一个位置,有两种思路,一是使用散列表中的另一个位置。二是修改散列表的结构,使得散列表中的每个位置可以表示多个值。
这样列下散列冲突的处理类型分两种:
①开放定址法---对应第一种思路,总是为冲突的key在散列表中寻找下一个“未被使用”的位置。
②链地址法-----对应第二种思路,每个散列表中的位置可以指向一个链表,该链表称为桶。每个桶中则可以存放多个value。(将冲突的key对应的value插入到链表中)
开放定址法又分为三种情况:
❶线性探测开放定址----易产生一次聚集现象,即多个key问题被hash到同一个索引位置上。对于每个(key,value)只要表不满,总可以找到一个位置存放。
❷二次探测开放定址
❸再散列法---对冲突的key再进行一次hash。
散列之HashTable学习的更多相关文章
- 数据结构和算法 – 7.散列和 Hashtable 类
7.1.散列函数 散列是一种常见的存储数据的技术,按照这种方式可以非常迅速地插入和取回数据.散列所采用的数据结构被称为是散列表.尽管散列表提供了快速地插入.删除.以及取回数据的操作,但是诸如查找最大值 ...
- PHP密码散列算法的学习
不知道大家有没有看过 Laravel 的源码.在 Laravel 源码中,对于用户密码的加密,使用的是 password_hash() 这个函数.这个函数是属于 PHP 密码散列算法扩展中所包含的函数 ...
- 哈希表(散列)HashTable实现
近期刷Leetcode发现凡是找字符串中反复字符或者数组中找反复数据的时候就不知道从何下手了. 所以决定学习一下哈希表解题.哈希表的原理主要是解决分类问题,hash表是介于链表和二叉树之间的一种中间结 ...
- 流畅的python第十章序列的修改,散列和切片学习记录
只要实现了__len__和__getitem__两个方法即可将该类视为序列. 切片原理 动态存取属性 如果实现了__getattr__方法,也要定义__setattr__方法,以防对象行为不一致
- js 实现数据结构 -- 散列(HashTable)
原文: 在Javascript 中学习数据结构与算法. 概念: HashTable 类, 也叫 HashMap 类,是 Dictionary 类的一种散列表实现方式. 散列算法的作用是尽可能快地在数据 ...
- 基于散列的集合 HashSet\HashMap\HashTable
HashSet\HashMap\HashTable 1 基于散列的集合 2 元素会根据hashcode散列,因此,集合中元素的顺序不一定与插入的顺序一致. 3 根据equals方法与hashCode方 ...
- 散列表碰撞处理、开链法、HashTable散列
散列表碰撞处理.开链法.HashTable散列 /** * 散列表碰撞处理.开链法.HashTable散列. * 将数组里的元素位置,也设置为数组,当两个数据的散列在同一个位置时, * 就可以放在这个 ...
- Shiro入门学习之散列算法与凭证配置(六)
一.散列算法概述 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5.SHA等,一般进行散列时最好提供一个salt(“盐”),什么意思?举个栗子 ...
- 【数据结构与算法Python版学习笔记】查找与排序——散列、散列函数、区块链
散列 Hasing 前言 如果数据项之间是按照大小排好序的话,就可以利用二分查找来降低算法复杂度. 现在我们进一步来构造一个新的数据结构, 能使得查找算法的复杂度降到O(1), 这种概念称为" ...
随机推荐
- file_put_contents () failed to open stream: Permission denied 解决办法
今天,帮朋友配置服务器thinkphp5的时候,直接访问“www.***.com/admin/index/index” : 出现以下错误: file_put_contents (/PHP/admin/ ...
- PostgreSQL之Sequence序列(转)
本文转载自:https://blog.csdn.net/omelon1/article/details/78798961 Sequence序列 Sequence是一种自动增加的数字序列,一般作为行或者 ...
- Delphi 实现获取其他程序的子窗体
通过一个父窗体的句柄,递归的枚举它的子窗体,我们可以最终找到需要的子窗体. 用法如下: nParentHandle: HWnd; nChildHandle: HWnd; nParentHandle : ...
- python----面对对象三大特征2
多态 什么是多态?多态指的是一类事物有多种形态,例如一个动物类,狗和猫都通过继承动物类来得来,这样我们可以将狗.猫称作动物类的另一种形态. 在java中也存在多态,java中的多态是用来解决在一个函数 ...
- hashCode和equal
转自:https://www.cnblogs.com/dolphin0520/p/3681042.html hashCode方法在Object类中: public native int hashCod ...
- MT【31】傅里叶级数为背景的三角求和
接下来要讲的这道题,背景有点复杂,不要求99%的学生看的懂背景,但是解答过程中涉及的反证法以及第二数学归纳法对自主招生的学生来说倒是不错的学习机会. 解答: 评 : 本题的背景为高等数学中的傅里叶分析 ...
- NOI 笔试题库(我背不住的部分)
吐槽 为什么C++选手要会编译Pascall啊!为什么Emacs选手要会使用Vim啊! Linux 中为文件改名使用的命令是:mv 在Linux 中删除当前目录下的test 目录的命令是:rm -r ...
- 洛谷 P3253 [JLOI2013]删除物品 解题报告
P3253 [JLOI2013]删除物品 题目描述 箱子再分配问题需要解决如下问题: (1)一共有\(N\)个物品,堆成\(M\)堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能 ...
- cf827D Best Edge Weight (kruskal+倍增lca+并查集)
先用kruskal处理出一个最小生成树 对于非树边,倍增找出两端点间的最大边权-1就是答案 对于树边,如果它能被替代,就要有一条非树边,两端点在树上的路径覆盖了这条树边,而且边权不大于这条树边 这里可 ...
- 拆分string 用空格 逗号
string that have both comma and space struct tokens: std::ctype<char>{ tokens(): std::ctype< ...