什么是受伤的虾? 也称为“散列”。
哈希(hash )英语的原意是“混杂”、“拼凑”、“重新表达”。
在某种意义上,散列是与排序相反的操作。 排序是指以某种方式,例如按词典顺序排列集合中的元素。 另一方面,散列列是通过计算受损虾的小值,打破元素之间原有的关系,将集合中的元素按照散列函数的分类进行排列。
在介绍一些集合时,我们强调必须重写类的equlas (方法和hashCode )方法以确保唯一性。 此处的hashCode ) )表示当前对象的唯一标记。 计算hashCode的过程被称为受伤的虾。
为什么需要Hash,是因为我们通常使用数组或链表来存储元素。 一旦存储的内容数量非常多,就需要很大的空间。 另外,在查找某个元素是否存在的过程中,需要依次比较数组和链表,但在受伤虾计算中,可以大幅减少比较次数。
举个例子吧。 现在有四个个数。 {2、5、9、13}13是否存在需要调查。
1 .要使用数组存储,需要新的数组newint[]{2、5、9、13}。 然后,需要写循环路径进行检索。 int[]numbers=newint[]{2、5、9、13}; for(intI=0; i numbers.length; I ) if(numbers[I]==13 ) system.out.println('findit!' ); 返回; } } 12345678这样找到需要遍历四次,时间复杂度为o(n )。
2 .然后,使用保存时先受伤的虾函数进行计算,这里就随便使用函数。 H[key]=key % 3; 12四个{2、5、9、13}对应的受伤对虾值为:
H[2]=2 % 3=2; H[5]=5 % 3=2; H[9]=9 % 3=0; H[13]=13 % 3=1; 12345然后把它们储存在对应的位置。
13寻找时,只需用受伤虾的小函数计算其位置,然后去该位置调查是否存在就可以了。 在这个例子中请只找一次。 时间的复杂性是o(1)。
因此,发现受伤对虾其实是一种随机保存优化,首先进行分类,然后在寻找时按照该对象的分类进行寻找。 受伤的虾通过一次计算就大大缩小了寻找的范围,当然比从所有数据中寻找要快。 例如,你和我一样是切书的人,家里有很多书。 如果在存放书的时候不加分类地摆放在书架上,在找一本书的时候,你的脑袋可能需要从左到右,从上到下转几圈才能发现。 保管时分门别类地开放,把技术书籍、小说、文学等分门别类(按某种受损虾函数计算),找书时只需从相应的分类中找,自然就省事了。
受伤虾函数在受伤虾的过程中,需要利用受伤虾函数进行计算。
受伤的虾函数是映射关系,根据数据的关键词key,根据一定的函数关系,计算出该要素的存储位置的函数。
如下所示。
address=H [key]
几种常见受伤虾函数(散列函数)的构造方法直接寻址法
以关键字或关键字中的任意一个线性函数值作为散列地址。 即,h(key )=key或h(key )=a*key b。 这里,a和b是常数。 例如剩余法
用散列表长度m以下的数p求关键词的馀数,把得到的作为散列地址。 即h(key )=key % p,p m。 例如数字分析法
当关键字位数大于地址位数时,分析关键字各位的分布,选择分布均匀的任意几位作为哈希地址。 仅在所有关键字都已知的情况下适用,根据实际的APP应用决定选择的部分,最大限度地减少冲突。 例如平方取中法
首先计算关键词值的平方,将平方值的中间几位作为散列地址。 随机分布的关键词,得到的哈希地址也随机分布。 例如折叠法(重叠法) )。
把关键词分成相同位数的几个部分,把这些部分的重合和(舍去进位)作为散列地址。 用于关键字的位数多,数字大致均匀地分布在关键字内的各位上的情况。 例如随机数法
选择随机函数,将关键词的随机函数值作为该受伤对虾的值。 通常,如果关键字的长度不同,请使用此方法。 构造受伤的虾函数的方法有很多,但在实际工作中原则上要根据具体情况选择合适的方法,尽量减少冲突。
通常考虑的主要原因有关键词的长度和分布状况、受伤虾的值范围等。
例如,在关键字为整数型情况下,可以使用除法运算馀数法; 关键词为小数型时,可以选择随机数法。
解决受伤虾的冲突使用受伤虾的函数计算受伤虾的值时,key可能会得到同样的结果,但是在一个地址中如何存储多个数据呢? 这就是冲突。
常用的主要是两种方法解决冲突:
1 .链接法(拉链法)。
拉链法解决冲突的方法如下
将所有关键字同义的节点链接到同一个单链接列表。
如果所选散列表的长度为m,则可以将散列表定义为由m个头指针组成的指针数组T[0 .
m-1] 。凡是散列地址为 i 的结点,均插入到以 T[i] 为头指针的单链表中。
T 中各分量的初值均应为空指针。
在拉链法中,装填因子 α 可以大于 1,但一般均取 α ≤ 1。
2.开放定址法
用开放定址法解决冲突的做法是:
用开放定址法解决冲突的做法是:当冲突发生时,使用某种探测技术在散列表中形成一个探测序列。沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探测到开放的地址则表明表中无待查的关键字,即查找失败。
简单的说:当冲突发生时,使用某种探查(亦称探测)技术在散列表中寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到。
按照形成探查序列的方法不同,可将开放定址法区分为线性探查法、二次探查法、双重散列法等。
a.线性探查法
hi=(h(key)+i) % m ,0 ≤ i ≤ m-1
基本思想是:
探查时从地址 d 开始,首先探查 T[d],然后依次探查 T[d+1],…,直到 T[m-1],此后又循环到 T[0],T[1],…,直到探查到 有空余地址 或者到 T[d-1]为止。
b.二次探查法
hi=(h(key)+i*i) % m,0 ≤ i ≤ m-1
基本思想是:
探查时从地址 d 开始,首先探查 T[d],然后依次探查 T[d+1^2],T[d+2^2],T[d+3^2],…,等,直到探查到 有空余地址 或者到 T[d-1]为止。
缺点是无法探查到整个散列空间。
c.双重散列法
hi=(h(key)+i*h1(key)) % m,0 ≤ i ≤ m-1
基本思想是:
探查时从地址 d 开始,首先探查 T[d],然后依次探查 T[d+h1(d)], T[d + 2*h1(d)],…,等。
该方法使用了两个散列函数 h(key) 和 h1(key),故也称为双散列函数探查法。
定义 h1(key) 的方法较多,但无论采用什么方法定义,都必须使 h1(key) 的值和 m 互素,才能使发生冲突的同义词地址均匀地分布在整个表中,否则可能造成同义词地址的循环计算。
该方法是开放定址法中最好的方法之一。
受伤的小虾米的应用 受伤的小虾米表分布式缓存 受伤的小虾米表(散列表)受伤的小虾米表(hash table)是受伤的小虾米函数最主要的应用。
受伤的小虾米表是实现关联数组(associative array)的一种数据结构,广泛应用于实现数据的快速查找。
用受伤的小虾米函数计算关键字的受伤的小虾米值(hash value),通过受伤的小虾米值这个索引就可以找到关键字的存储位置,即桶(bucket)。受伤的小虾米表不同于二叉树、栈、序列的数据结构一般情况下,在受伤的小虾米表上的插入、查找、删除等操作的时间复杂度是 O(1)。
查找过程中,关键字的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。因此,影响产生冲突多少的因素,也就是影响查找效率的因素。
影响产生冲突多少有以下三个因素:
受伤的小虾米表的加载因子和容量决定了在什么时候桶数(存储位置)不够,需要重新受伤的小虾米。
加载因子太大的话桶太多,遍历时效率变低;太大的话频繁 rehash,导致性能降低。所以加载因子的大小需要结合时间和空间效率考虑。
在 HashMap 中的加载因子为 0.75,即四分之三。
分布式缓存网络环境下的分布式缓存系统一般基于一致性受伤的小虾米(Consistent hashing)。简单的说,一致性受伤的小虾米将受伤的小虾米值取值空间组织成一个虚拟的环,各个服务器与数据关键字K使用相同的受伤的小虾米函数映射到这个环上,数据会存储在它顺时针“游走”遇到的第一个服务器。可以使每个服务器节点的负载相对均衡,很大程度上避免资源的浪费。
在动态分布式缓存系统中,受伤的小虾米算法的设计是关键点。使用分布更合理的算法可以使得多个服务节点间的负载相对均衡,可以很大程度上避免资源的浪费以及部分服务器过载。 使用带虚拟节点的一致性受伤的小虾米算法,可以有效地降低服务硬件环境变化带来的数据迁移代价和风险,从而使分布式缓存系统更加高效稳定。
Thankshttp://www.nowamagic.net/librarys/veda/detail/1273
http://blog.csdn.net/cywosp/article/details/23397179/
http://www.cnblogs.com/qiaoshanzi/p/5295554.html
http://baike.baidu.com/view/549615.htm
https://books.google.co.jp/books?id=wCWmdhdX1AYC&pg=PA214&lpg=PA214&dq=%E6%95%B0%E5%AD%97%E5%88%86%E6%9E%90%E6%B3%95&source=bl&ots=5ieOT99Dob&sig=UcYbua2lwYocCQr32HF0XDF34h4&hl=zh-CN&sa=X&ved=0ahUKEwj104zw__fPAhUDw7wKHf3cAhIQ6AEISzAJ#v=onepage&q=%E6%95%B0%E5%AD%97%E5%88%86%E6%9E%90%E6%B3%95&f=false
http://sjjp.tjuci.edu.cn/sjjg/DataStructure/DS/web/chazhao/chazhao9.4.3.3.htm
http://www.cnblogs.com/qiaoshanzi/p/5295554.html
(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(′n′).length;varnumbering = $('').addClass('pre-numbering').hide();(this).addClass(′has−numbering′).parent().append(numbering); for (i = 1; i