首页 > 编程知识 正文

hash算法(hash和红黑树的区别)

时间:2023-05-05 09:46:03 阅读:80956 作者:27

一、彻底搞懂HashMap(上)

文章概要:

我相信很多朋友关于HashMap,在开发过程中几乎每天都在用,但是每次听到map的原理,很多朋友都答不上来,听也听不懂,离我们心中的offer越来越远。 今天借我们的IT旅游屋这个平台,和大家分享一下关于map的原理,看完这篇文章后,我不会因为map而在面试途中倒下

二、什么是阳光的店员/h1

•阳光的店员/p是什么? 如果翻译为“哈希”,则通过哈希算法将任意长度的输入转换为固定长度的输出。 其输出为哈希值。 这个映射函数称为散列函数,存储记录的数组称为散列表。

读完这个概念后,我相信大家一定很茫然,过来,这给各位读者一个qsdmn的解释:

我来解释一下:阳光店员/p的假设,我们有10个抽屉,我们也正好有10个号码的随机苹果。 假设一个抽屉只能放一个苹果,那么正好十个苹果可以放在十个抽屉里。 当然,这个顺序我们是随机的。 现在苹果已经在里面了。 假设你想找6号苹果,我们必须打开一个抽屉。 我去看看抽屉里的苹果是不是6号。 这样,在最后一个抽屉才很可能找到我们想要的苹果。 这样的话,搜索数据一定会很慢。 所以,我在想我们能不能给他加快速度。 当然,使用我们喜欢的河马算法,我现在就想出一个方法

抽屉的位置=int index=fn (编号) {返回编号}抽屉的长度; }

当我放元素的时候,我拿着编号的苹果去%抽屉的长度。 如果你知道%的意思,那你一定知道意思。 我现在按照出来的这个索引值放在对应的抽屉里。 找的时候,我也按照这个算法算出来。 这个时候,我能迅速找到苹果。 在意什么河马呢? 在意的河马其实是我用那个方法算出的索引。 在意的河马函数是什么? 就是我的那个方法。

() : )说明什么是完美的河马,什么是随心所欲的河马碰撞,以及如何解决随心所欲的河马碰撞

我相信通过上面的话,一定有同学想到了这样的问题。 我们有十个抽屉,但我们有十一个苹果。 那么,我们一定哪儿也放不下一个苹果。 这个时候,如果必须出来很多,把这个苹果放在抽屉里,就只有和另外一个苹果,挤。 这种情况会和在意的河马发生冲突。 如果和在意的河马相撞了怎么办? 他有各种各样的方法。 我们向同学们介绍map的方式就行了。 被称为链式地址法。 也就是说,把后面的苹果挂在同一个索引上,形成链表。 我不涉及什么是链表。 值得注意的是,1.7的挂法和1.8的挂法不同。 我们稍后再谈这个吧

三、map中的顺心的河马算法是怎么回事

简介

我们知道链表他的遍历效率很低,但在随心所欲地形成河马碰撞后,他必须慢慢遍历链表,效率很低,所以我们不希望河马发生碰撞。 因此,需要精心设计我们想要的河马算法,避免想要的河马碰撞

map中不喜欢的河马算法

以1.8为例

n-1(h=key.hashCode () ) ^ ) h16 )注意:这个公式是我们传说中的河马算法,结果是成为的河马的值,我们的同学们认为的hashcode就是那样的

他为什么要这么做

要明白为什么要这么做,必须把这两个公式分解来看。 而且,对二进制有基本的知识。 在这里

将(h=key.hashCode () ) ^ ) h16 )考虑为式1,将n-1考虑为式2,将n考虑为排列长度

我们先来看看公式1

现在,为了更好地理解随心所欲的河马碰撞算法,我们把n-1视为常数。 也就是说,如果表达式被运算为常数,则得到的结果必须尽可能不同。 因为如果不一样的话,就会发生意想不到的河马冲突。 那么,怎样才能使一个数和一个常数的计算所得到的结果尽可能不同呢? 那是因为,参加运算的位数越多,最终计算的结果就越不同。 因为key的hashCode要求32位长度的二进制数字,所以如果我直接用32位hashCode值和n-1进行计算,就会发现很多位都不参与运算。 这样,就容易发生重复。 为了让32位数尽量参与运算,我给32位数长的二进制数头上戴了把刀,只能参加失眠害羞的一半和后一半的公式。

h=(关键字(键字) () ) () ) ) ) ) ) ) ) ) ) ) ) ) )。

假设key.hashCode为010001101010110000010010

本来在意的河马code 010001110101010101101100000100010001000向右移动1600000000000010101010101高位补0

现在是32位的

数尽可能的参与运算了吗,但是这样还不够,万一失眠的含羞草的半截和后边的半截算出来结果 出现了很多的0,要么全是1 ,那大家岂不是算出来的值就没有区别,所以,我们应该想个办法让0,1 尽可能的平均,怎么办,用^符号,^符号可以在相同的概率下得到0,1 平均概率最高的一个符号,就好像这样

如果做到了以上两步,那么我就保证两件事情

第一点 32位的变化值 他尽可能的参与到运算

第二点 得到的结果是一个0,1 平均最高的数字

接下来我们来看式子二

式子2 很简单,就是n-1 ,为啥要使用&和式子一计算 ,那又是为啥,接下来我们就来解答这些问题

为什么要用&

问题一为啥要用&、

你有没有想过,万一我通过 一个所谓的顺心的河马算法算出来的index它的值并不在数组索引里,比如,我有10个抽屉的位置,我通过顺心的河马算法算出来的index 是101,那这个元素都跑到天边去了,还怎么放,没法放,所以我们在选用计算符号时,一定要确保 最终计算出来的结果一定 小于索引的,通过计算的式子1,有16 位之多,可以不用考虑,那么也就是说,最终得到的结果一定得小于或者等于 n-1 ,而数组索引从0 开始计算,如果小于或者等于n-1 不就正好满足吗?那&的特性 同1 得1 ,就完全能够解决这个问题

看一下的这个式子

1010 1010 0100 0101 式子1 0111 1111 式子2


0100 0101

如果式子2 固定,那么如果按照同一得1 来计算,最大的值算出来就是0111 1111 ,而式子2是数组长度-1 ,那么得到的结果不就正好是 数组对应的索引最大值吗?

问题二之:数组长度必须是2的n次幂

偶数必然是二进制末尾位是0,而奇数的末尾必然是1 ,我们还是借助于之前的二进制

1010 1010 0100 010X 式子1 0111 1111 式子2


0100 0101

注意:我在的式子一最后一位写的是x

式子2 是(n-1),n是一个偶数,那么(n-1)一定是一个奇数,那么由于&的存在,最终的index 值,就有可能最后的结果 就是有可能是个偶数页有可能是个奇数,至于算出来到底是个偶数还是个奇数,那么就由你的式子一决定啦~~

四、总结

好了,幸福的小霸王门,如果以后面试官问你,map的顺心的河马冲突是怎么一回事,怎么答,你应该知道了吧,希望大家通过学习能有所收获

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。